多线程 如何自己实现定时器
Posted Perceus
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程 如何自己实现定时器相关的知识,希望对你有一定的参考价值。
@TOC
什么是定时器
定时器是多线程编程中的一个重要的组件
好比一个闹钟 定好一个时间让一个线程去执行
定时器在网络编程中特别常见
比如:
那么,我们就可以使用 代码中的定时器,来实现类似的功能。
先介绍标准库的定时器用法,然后再看看如何自己实现一个定时器
标准库的定时器用法
schedule
方法,有两个参数
:
任务
多长时间之后执行
如何自己实现一个定时器
一个问题:Timer 类 的内部需要什么东西?
从Timer
的 工作内容入手
- 管理很多的任务
- 执行时间到了的任务
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");
以上是关于多线程 如何自己实现定时器的主要内容,如果未能解决你的问题,请参考以下文章
29多线程(线程池定时器)将一个文件复制多次拆分文件并合并多线程复制文件