eight
2024-08-21 3c2ee852994cc3c4d861484f12d972b42cb0ffee
并发问题 修改
已修改2个文件
已重命名1个文件
83 ■■■■■ 文件已修改
jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/dal/mysql/queue/queueMapper.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/listener/MySpringEventListener.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/queueServiceImpl.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/dal/mysql/queue/queueMapper.java
@@ -79,4 +79,12 @@
            " order by seq_num" +
            "</script>")
    List<QueueDO> getDoctorQueueByStatus(@Param("roomId")Long roomId, @Param("bedNo")String bedNo, @Param("statusList")List<Byte> statusList);
    @Update("update lihu.queue set status = #{newStatus}, room_id = #{roomId}, room_name = #{roomName}, \n" +
            " bed_no = #{bedNo}, seq_num = #{seqNum} where id = \n" +
            "  (select a.id from \n" +
            "    (select id from lihu.queue where status = #{curStatus} order by book_timeslot, create_time limit 1) a)")
    Integer preemptPatient(@Param("roomId")Long roomId, @Param("roomName")String roomName, @Param("bedNo")String bedNo,
                           @Param("seqNum")Integer seqNum, @Param("curStatus")Byte curStatus, @Param("newStatus")Byte newStatus);
}
jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/listener/MySpringEventListener.java
ÎļþÃû´Ó jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/MySpringEventLister.java ÐÞ¸Ä
@@ -1,21 +1,22 @@
package cn.lihu.jh.module.ecg;
package cn.lihu.jh.module.ecg.listener;
import cn.lihu.jh.module.ecg.service.queue.QueueService;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
public class MySpringEventLister implements ApplicationListener<ApplicationStartedEvent> {
public class MySpringEventListener {
    @Resource
    private QueueService queueService;
    @Override
    @EventListener
    public void onApplicationEvent(ApplicationStartedEvent event) {
        System.out.println("应用启动完成,通知监听器执行缓存预加载操作");
        queueService.initQueue();
        queueService.hurryup();
    }
}
jh-module-ecg/jh-module-ecg-biz/src/main/java/cn/lihu/jh/module/ecg/service/queue/queueServiceImpl.java
@@ -17,10 +17,8 @@
import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import static cn.lihu.jh.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.lihu.jh.module.ecg.enums.ErrorCodeConstants.*;
@@ -40,6 +38,8 @@
    PriorityBlockingQueue<BedQueueBO> priorityQueue = new PriorityBlockingQueue<>();
    ConcurrentHashMap<String, BedQueueBO > mapBedVsQueue = new ConcurrentHashMap<>();
    ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
    @Resource
    private queueMapper queueMapper;
@@ -116,9 +116,7 @@
        });
        Integer num = queueMapper.getMaxSeqNum();
        curSeqNum = new AtomicInteger(null == num ? 1 : ++num);
        hurryup();
        curSeqNum = new AtomicInteger(null == num ? 0 : num);
    }
    public void reorderQueue() {
@@ -146,34 +144,50 @@
            if (null == bedQueueBO)
                return;
            if (bedQueueBO.queueNum.get() == bedQueueBO.maxQueueNum)
            int curQueueNum = bedQueueBO.queueNum.get();
            if (curQueueNum > bedQueueBO.maxQueueNum)
                throw new RuntimeException("exceed max queue number!");
            if (curQueueNum == bedQueueBO.maxQueueNum)
                return;
            QueueDO  queue = queueMapper.getFirstInQueueByStatus(QueueStatusEnum.WAITING.getStatus());
            if (null == queue)
                return;
            Integer updateNum = queueMapper.preemptPatient(
                    bedQueueBO.getRoomId(),
                    bedQueueBO.getRoomName(),
                    bedQueueBO.getBedNo(),
                    curSeqNum.get() + 1,
                    QueueStatusEnum.WAITING.getStatus(),
                    QueueStatusEnum.READY.getStatus());
            queue.setStatus(QueueStatusEnum.READY.getStatus()); //候诊准备中
            queue.setRoomId(bedQueueBO.getRoomId());
            queue.setRoomName(bedQueueBO.getRoomName());
            queue.setBedNo(bedQueueBO.getBedNo());
            queue.setSeqNum(curSeqNum.get());
            queueMapper.updateById(queue);  // queue.getId();
            // æ²¡æœ‰æŠ¢åˆ°æŽ’队患者
            if (null == updateNum || 0 == updateNum) {
                return;
            }
            curSeqNum.getAndIncrement();
            bedQueueBO.queueNum.getAndIncrement();
            BedQueueBO bedQueueBO2 = priorityQueue.poll();
            priorityQueue.offer(bedQueueBO2);
            // å¯èƒ½å·²ç»ã€å¹¶å‘的】在 nextPatient ä¸­æ”¹å˜äº†å€¼
            bedQueueBO.queueNum.incrementAndGet();
            // å¯èƒ½å·²ç»ã€å¹¶å‘的】在 nextPatient ä¸­æ”¹å˜äº†ä¼˜å…ˆé˜Ÿåˆ—顺序
            priorityQueue.remove(bedQueueBO);
            priorityQueue.offer(bedQueueBO);
        }
    }
    /**
     * é¢„约确认后的排队
     * @param queueSaveReqVO
     */
    @Override
    public void queue(QueueSaveReqVO queueSaveReqVO) {
        queueSaveReqVO.setStatus(QueueStatusEnum.WAITING.getStatus()); //排队中
        QueueDO queue = BeanUtils.toBean(queueSaveReqVO, QueueDO.class);
        queueMapper.insert(queue);  // queue.getId();
        queueMapper.insert(queue);
        hurryup();
        singleThreadExecutor.submit( () -> {
            hurryup();
        });
    }
    private void nextPatient(Long roomId, String bedNo) {
@@ -183,18 +197,19 @@
        // ä¼˜å…ˆé˜Ÿåˆ—中 è¯¥å·¥ä½ å°±è¯Šå‡†å¤‡ä¸­äººçš„æ•°é‡ å‡ä¸€
        BedQueueBO bo = mapBedVsQueue.get(String.format("%09d%s", roomId, bedNo));
        boolean breturn = priorityQueue.remove(bo);
        bo.queueNum.getAndDecrement();
        bo.queueNum.getAndDecrement(); // å¯èƒ½å·²ç»ã€å¹¶å‘的】在 hurry-up ä¸­æ”¹å˜äº†å€¼
        priorityQueue.remove(bo);
        priorityQueue.offer(bo);
        hurryup();
        singleThreadExecutor.submit( () -> {
            hurryup();
        });
    }
    public void finishNextPatient(Long roomId, String bedNo) {
        // ä»Ž DB æŠŠ å°±è¯Šä¸­çš„人 è®¾ç½®ä¸ºå°±è¯Šå®Œæˆ
        Integer ret =  queueMapper.updateQueueStatus(roomId, bedNo,
                QueueStatusEnum.ONSTAGE.getStatus(), QueueStatusEnum.FINISH.getStatus());
        System.out.println("完成数量: " + ret);
        nextPatient(roomId, bedNo);
    }
@@ -203,7 +218,6 @@
        // ä»Ž DB æŠŠ å°±è¯Šä¸­çš„人 è®¾ç½®ä¸ºè¿‡å·
        Integer ret =  queueMapper.updateQueueStatus(roomId, bedNo,
                QueueStatusEnum.ONSTAGE.getStatus(), QueueStatusEnum.PASSED.getStatus());
        System.out.println("完成数量: " + ret);
        nextPatient(roomId, bedNo);
    }