思路
如果有多个周期任务 需要线程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();
}
结果
可以发现工作线程都是一个 但实现了执行不同时间周期的任务