多线程 如何自己实现定时器

弱龄寄事外,委怀在琴书。这篇文章主要讲述多线程 如何自己实现定时器相关的知识,希望能为你提供帮助。
@TOC
什么是定时器

  • 定时器是多线程编程中的一个重要的组件
  • 好比一个闹钟 定好一个时间让一个线程去执行
  • 定时器在网络编程中特别常见
比如:
那么,我们就可以使用 代码中的定时器,来实现类似的功能。
先介绍标准库的定时器用法,然后再看看如何自己实现一个定时器
标准库的定时器用法schedule方法,有两个参数
  1. 任务
  2. 多长时间之后执行
多线程 如何自己实现定时器

文章图片

如何自己实现一个定时器一个问题:Timer 类 的内部需要什么东西?
Timer 的 工作内容入手
  1. 管理很多的任务
  2. 执行时间到了的任务
1. 描述任务
// 创建一个类,来描述一个具体的任务 class MyTask // 任务具体要做什么 private Runnable runnable; // 任务具体的执行时间:保存任务要执行的毫秒级时间戳 private long time; // after 是一个时间间隙,不是绝对的时间戳的值 public MyTask(Runnable runnable,long after) this.runnable = runnable; // 很简单,意思就是从当前时间开始, after 秒之后,这个任务被执行。 this.time = System.currentTimeMillis()+after; // 通过调用这里 run方法,来执行我们任务具体要做什么 public void run() runnable.run();

2. 组织任务
多线程 如何自己实现定时器

文章图片

3. 执行时间到了的任务
多线程 如何自己实现定时器

文章图片

【多线程 如何自己实现定时器】上述代码中存在两个非常严重的问题!!!
多线程 如何自己实现定时器

文章图片

代码
import java.util.concurrent.PriorityBlockingQueue; // 创建一个类,来描述一个具体的任务 class MyTask implements Comparable< MyTask> // 任务具体要做什么 private Runnable runnable; // 任务具体的执行时间:保存任务要执行的毫秒级时间戳 private long time; // after 是一个时间间隙,不是绝对的时间戳的值 public MyTask(Runnable runnable,long after) this.runnable = runnable; // 很简单,意思就是从当前时间开始, after 秒之后,这个任务被执行。 this.time = System.currentTimeMillis()+after; // 通过调用这里 run方法,来执行我们任务具体要做什么 public void run() runnable.run(); public long getTime() return time; @Override public int compareTo(MyTask o) return (int) (this.time - o.time); class MyTimer // 定时器内部要能够存放多个任务 private PriorityBlockingQueue< MyTask> queue = new PriorityBlockingQueue< > (); public void schedule(Runnable runnable,long after) MyTask task = new MyTask(runnable,after); queue.put(task); synchronized(locker) locker.notify(); private Object locker = new Object(); public MyTimer() Thread t = new Thread(()-> while(true) try // 取出队首元素 MyTask task =queue.take(); //再比较一下看看当前这个任务时间到了没 long curTime = System.currentTimeMillis(); // 拿当前时间 和 任务执行时间进行比较 if(curTime < task.getTime()) //时间还没到,把任务再塞回到队列中 queue.put(task); // 指定一个等待时间 synchronized(locker) locker.wait(task.getTime() - curTime); else // 时间到了,执行这个任务 task.run(); catch (InterruptedException e) e.printStackTrace(); ); t.start(); public class Test25 public static void main(String[] args) MyTimer myTimer = new MyTimer(); myTimer.schedule(new Runnable() @Override public void run() System.out.println("hello timer"); ,3000); System.out.println("main");


    推荐阅读