Java查询时间段(startTime
350
2022-07-22
目录前言1.描述任务2.组织任务3.执行时间到了的任务
前言
像是一个闹钟定时,在一定时间之后被唤醒并执行某个之前设定好的任务,join(指定超时时间),sleep(指定休眠时间)都是基于系统内部的定时器来实现的。java.util.Timer核心方法就一个,schedule参数有两个:任务是啥(一段代码),多长时间之后执行
public class 定时器 {
public static void main(String[] args) {
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("hello timer");
}
}, 3000);
}
}
Timer内部组成
1.描述任务
创建一个专门的类来表示一个定时器的任务TimerTask,这个MyTask类的比较规则不是默认存在的,需要我们手动指定按照时间大小来比较的。
//创建一个类表示一个任务
class MyTask{
//任务描述
private Runnable runnable;
//任务具体啥时候干
private long time;
//after是一个时间间隔,不是觉得时间戳的值
public MyTask(Runnable runnable, long after){
this.runnable = runnable;
this.time = System.currentTimeMillis() + after;
}
public void run(){
runnable.run();
}
}
2.组织任务
通过一定的数据结构把一些任务给放到一起,标准库有一个专门的数据结构PriorityQueue,这里用到的数据结构是PriorityBlockingQueue,及带有优先级又带有阻塞队列。此处的队列要考虑到线程安全问题,可能在多个线程里进行注册任务,同时还有一个专门的线程来取任务执行,此时的队列就需要注意线程安全问题。其次为了避免盲等的现象,可以使用wait这样的机制指定等待时间时间到了自然唤醒,计算出当前时间和任务目标的时间差即可。既然是指定一个等待时间为啥不用sleep而是用wait,sleep不能被中途唤醒,wait能够被中途唤醒。在等待过程中可能有新的任务插入,新的任务是可能出现在之前所有任务的最前面,在schedule操作中就需要加上一个notify操作。
3.执行时间到了的任务
需要执行时间最靠前的任务,就需要一个线程不停地去检查当前优先队列的对手元素,看看当前最靠前的任务是不是时间到了
class MyTask implements Comparable
//任务描述
private Runnable runnable;
//任务具体啥时候干
private long time;
//delay是一个时间间隔,不是绝对时间戳的值
public MyTask(Runnable runnable, long delay){
this.runnable = runnable;
this.time = System.currentTimeMillis() + delay;
}
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 Object locker = new Object();
//定时器内不要能够存放多个任务
private PriorityBlockingQueue
public void schedule(Runnable runnable, long delay){
MyTask task = new MyTask(runnable, delay);
queue.put(task);
//每次任务插入成功之后都唤醒一下扫描线程,让线程重新检查队首的任务是否时间到要执行
synchronized (locker){
locker.notifygHDZFQc();
}
}
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();
}
}
});
tgHDZFQc.start();
}
}
public class 定时器 {
public static void main(String[] args) {
MyTimer myTimer = new MyTimer();
myTimer.schedule(new Runnable() {
@Override
public void run() {
System.out.println("hello timer");
}
}, 3000);
myTimer.schedule(new Runnable() {
@Override
public void run() {
System.out.println("hello ");
}
}, 2000);
}
}
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~