quasar-利用协程执行周期任务

235 阅读1分钟

思路

如果有多个周期任务 需要线程sleep来执行 ,可以切换成协程节省线程开销

code

quasar依赖

<dependency>
   <groupId>co.paralleluniverse</groupId>
   <artifactId>quasar-core</artifactId>
   <version>0.7.9</version>
   <classifier>jdk8</classifier>
</dependency>

周期任务实体

@AllArgsConstructor
class Job{
    int period;//秒
    Runnable runnable;
}

载体线程

  class MyFiberScheduleThread extends Thread{
      Job[] jobs;
      List<Fiber<Void>> fibers;

      public MyFiberScheduleThread(Job... jobs) {
          this.jobs = jobs;
      }

      @Override
      public void run() {
          fibers=new ArrayList<>();
          for (Job job : jobs) {

              Fiber<Void> fiber = new Fiber<>(scheduler,()->{
                  for (;;){
                      Fiber.sleep(job.period*1000L);
                      job.runnable.run();

                      //先run再睡似乎会出现重叠的 猜测 j1 执行后没睡 切到j2 又没睡切到j3
//                      job.runnable.run();
//                      Fiber.sleep(job.period*1000L);

                  }

              });

              fibers.add(fiber);
          }

          for (Fiber<Void> fiber : this.fibers) {
              fiber.start();
          }

          /*让线程卡住 下面语句应该永远执行不完*/
          try {
              fibers.get(0).join();
          } catch (ExecutionException e) {
              e.printStackTrace();
          } catch (InterruptedException e) {
              e.printStackTrace();
          }
      }

  }
  

测试

@Test public void test() throws InterruptedException {
    MyFiberScheduleThread scheduleThread = new MyFiberScheduleThread(
            new Job(1,()->log.info("{}-j1-1执行",Thread.currentThread().getName())),
            new Job(1,()->log.info("{}-j1-2执行",Thread.currentThread().getName())),

            new Job(2,()->log.info("{}-j2-1执行",Thread.currentThread().getName())),
            new Job(2,()->log.info("{}-j2-2执行",Thread.currentThread().getName())),

            new Job(3,()->log.info("{}-j3-1执行",Thread.currentThread().getName())),

            new Job(4,()->log.info("{}-j4-1执行",Thread.currentThread().getName())),
            new Job(4,()->log.info("{}-j4-2执行",Thread.currentThread().getName())),
            new Job(4,()->log.info("{}-j4-3执行",Thread.currentThread().getName())),

            new Job(5,()->log.info("{}-j5-1执行",Thread.currentThread().getName())),
            new Job(5,()->log.info("{}-j5-2执行",Thread.currentThread().getName()))


    );
    scheduleThread.setName("my-scheduleThread");

    scheduleThread.start();

    scheduleThread.join();
}

结果

可以发现工作线程都是一个 但实现了执行不同时间周期的任务

图片.png