自制--一个线程管理多个周期任务

218 阅读2分钟

思路

一个线程管理所有周期任务 自身用一个比较短的时间睡眠 形成帧 利用时间差值判断某个任务是否达到了执行条件

周期任务实体

   @Setter@Getter@AllArgsConstructor
    class Schedule{
        String name;
        Runnable runnable;
        long period;
​
        public void run(){
            runnable.run();
        }
    }

工作线程

    class ManagerThread extends Thread{
​
        long lastTime;
        long frame = 50;//50ms
​
        Node[] nodes;
​
        @Getter@Setter
        class Node{
            Schedule schedule;
            long delay;
​
            public Node(Schedule schedule) {
                this.schedule = schedule;
                this.delay = schedule.period;
            }
​
            void resetDelay(){
                this.delay = schedule.period;
            }
        }
​
        public ManagerThread(Schedule... schedules) {
            nodes = new Node[schedules.length];
            for (int i=0;i<schedules.length;i++){
                nodes[i] = new Node(schedules[i]);
            }
​
        }
​
​
        long getDeltaTime(){
            return System.currentTimeMillis()-lastTime;
        }
​
        @Override
        public void run() {
            lastTime = System.currentTimeMillis();//第一次执行
            for (;;){
                long now = System.currentTimeMillis();
                //5x
                //log.info("frame start now={} lastTime={} deltaTime={}",now,lastTime,now-lastTime);
​
                /* 处理队列中的*/
                for (int i=0;i<nodes.length;i++){
                    Node node = nodes[i];
                    if (node==null)
                        continue;
//                    log.info("{} {}",node.delay,getDeltaTime());
                    if ((node.delay-=getDeltaTime())>0)
                        continue;
                    node.resetDelay();
​
                    node.getSchedule().run();
                 //如果这里run耗时 可能会堵死整个
​
                }
​
                /*睡前记录*/
                lastTime = System.currentTimeMillis();
​
                try {
                    Thread.sleep(frame);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
​
            }
​
        }
    }
​

测试

    @Test
    public void test(){
        ManagerThread managerThread = new ManagerThread(
                new Schedule("S1 1秒  1",()->log.info("S1"),1000L),
//                new Schedule("S11 一秒  11",()->log.info("S11"),1000L),
                new Schedule("S2 30秒  1",()->log.info("S2"),30000L),
                new Schedule("S3 2秒  1",()->log.info("S3"),2000L),
                new Schedule("S4 4秒  1",()->log.info("S4"),4000L),
​
                new Schedule("S5 1秒  1",()->log.info("S5"),1000L)
​
                );
        managerThread.setName("managerThread");
​
        managerThread.start();
​
        try {
            managerThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
​
    }

结果

14:27:52.767 [managerThread] INFO TestOneThreadMultiSchedule - S3
14:27:52.767 [managerThread] INFO TestOneThreadMultiSchedule - S5
14:27:53.790 [managerThread] INFO TestOneThreadMultiSchedule - S1
14:27:53.790 [managerThread] INFO TestOneThreadMultiSchedule - S5
14:27:54.539 [managerThread] INFO TestOneThreadMultiSchedule - S4
14:27:54.803 [managerThread] INFO TestOneThreadMultiSchedule - S1
14:27:54.803 [managerThread] INFO TestOneThreadMultiSchedule - S3
14:27:54.803 [managerThread] INFO TestOneThreadMultiSchedule - S5
14:27:55.819 [managerThread] INFO TestOneThreadMultiSchedule - S1
14:27:55.819 [managerThread] INFO TestOneThreadMultiSchedule - S5
14:27:56.836 [managerThread] INFO TestOneThreadMultiSchedule - S1
14:27:56.836 [managerThread] INFO TestOneThreadMultiSchedule - S3
14:27:56.836 [managerThread] INFO TestOneThreadMultiSchedule - S5
14:27:57.853 [managerThread] INFO TestOneThreadMultiSchedule - S1
14:27:57.853 [managerThread] INFO TestOneThreadMultiSchedule - S5
14:27:58.547 [managerThread] INFO TestOneThreadMultiSchedule - S4
14:27:58.869 [managerThread] INFO TestOneThreadMultiSchedule - S1
14:27:58.869 [managerThread] INFO TestOneThreadMultiSchedule - S3
14:27:58.869 [managerThread] INFO TestOneThreadMultiSchedule - S5
14:27:59.879 [managerThread] INFO TestOneThreadMultiSchedule - S1
14:27:59.879 [managerThread] INFO TestOneThreadMultiSchedule - S5
14:28:00.414 [managerThread] INFO TestOneThreadMultiSchedule - S2
14:28:00.892 [managerThread] INFO TestOneThreadMultiSchedule - S1
14:28:00.893 [managerThread] INFO TestOneThreadMultiSchedule - S3
14:28:00.893 [managerThread] INFO TestOneThreadMultiSchedule - S5
14:28:01.916 [managerThread] INFO TestOneThreadMultiSchedule - S1
14:28:01.916 [managerThread] INFO TestOneThreadMultiSchedule - S5
14:28:02.559 [managerThread] INFO TestOneThreadMultiSchedule - S4
14:28:02.930 [managerThread] INFO TestOneThreadMultiSchedule - S1
14:28:02.930 [managerThread] INFO TestOneThreadMultiSchedule - S3
14:28:02.930 [managerThread] INFO TestOneThreadMultiSchedule - S5
14:28:03.948 [managerThread] INFO TestOneThreadMultiSchedule - S1
14:28:03.948 [managerThread] INFO TestOneThreadMultiSchedule - S5
14:28:04.970 [managerThread] INFO TestOneThreadMultiSchedule - S1
14:28:04.970 [managerThread] INFO TestOneThreadMultiSchedule - S3
14:28:04.971 [managerThread] INFO TestOneThreadMultiSchedule - S5
14:28:05.981 [managerThread] INFO TestOneThreadMultiSchedule - S1
14:28:05.982 [managerThread] INFO TestOneThreadMultiSchedule - S5
14:28:06.566 [managerThread] INFO TestOneThreadMultiSchedule - S4
14:28:06.997 [managerThread] INFO TestOneThreadMultiSchedule - S1
14:28:06.997 [managerThread] INFO TestOneThreadMultiSchedule - S3
14:28:06.997 [managerThread] INFO TestOneThreadMultiSchedule - S5
14:28:08.007 [managerThread] INFO TestOneThreadMultiSchedule - S1
14:28:08.007 [managerThread] INFO TestOneThreadMultiSchedule - S5
14:28:09.030 [managerThread] INFO TestOneThreadMultiSchedule - S1
14:28:09.030 [managerThread] INFO TestOneThreadMultiSchedule - S3
14:28:09.030 [managerThread] INFO TestOneThreadMultiSchedule - S5
14:28:10.043 [managerThread] INFO TestOneThreadMultiSchedule - S1

\