,,Java中的定时器Timer详解

,,Java中的定时器Timer详解

本文主要详细介绍Java定时器Timer的用法。本文中的示例代码非常详细,具有一定的参考价值。感兴趣的朋友可以参考一下。

目录

摘要简单来说,定时器就相当于一个“闹钟”,给定时器设定一个任务,约定这个任务在xxx时间之后执行~

Timer类提供了一个核心接口。schedule指定一个任务给定时器,一定时间后再执行任务~

如何实现定时器的效果~

Timer应该包含一个任务类,每个任务代表一个特定的任务实例。任务包含一个时间戳(当任务被执行时)和一个可运行的实例(用于指示任务是什么)。

定时器通过优先级阻塞队列被组织成一个任务。

在这里,优先级是按照时间的顺序排列的,即将到达时间的任务优先级更高。

也就是在堆中加入wait/notify,这样可以起到阻塞的作用。

标准库提供了这样一个队列,PriorityBlockingQueue。

Timer还需要一个特殊的线程,不断扫描队列头元素,看是否可以执行。如果可以执行,就执行,否则继续在队列中等待。

具体如何用代码实现这样一个定时器Timer:

一般在设置时间的时候,入局时间是一个时间间隔。

例如:传入1000 ,就代表从当前开始过1000ms之后在执行;

而这里,为了下面代码的方便,我在这里记录了绝对时间,这样this.time就是一个标志的ms级时间戳。在后续中,我只需要获取当前时间戳,并与这里的时间进行比较。

任务应该放在优先级队列中,但是优先级需要在优先级队列中进行比较,因此任务类可以实现compare接口并重写compareTo方法进行比较。

在这里,我希望较短的时间线会满足。

这里,获取当前时间currTime。如果当前时间大于或等于任务中的约定时间,则在规定时间后完成,否则,将其移除。

将任务放回队列,继续等待。

这里还涉及到一个问题:

例如,如果你把闹钟设在早上8:30,你在8:00醒来,检查时间,在它到来之前你又回去睡觉。

但这里是while(真),意思是你要每秒钟看一次闹钟,8.01,8.02,这样会白白浪费一些资源,导致“瞎等”。在等待任务时间的过程中,你一直掌握着CPU资源~

所以这里需要优化一下:使用等待/通知机制可以改善盲目性等问题~

如果发现还没到出任务的时候,就等一等,等一定时间。这里使用的重载版wait()在wait()中写一个参数,达到等待时间自动唤醒~此时扫描次数和成本大大降低。

这里的notify()是为了确保如果有一个线程处于等待状态,它需要唤醒这个线程。

举个例子;

如果正在执行组长元素8.30,等待30分钟,但是这个时候可能会突然插入一个任务让你做8.10的事情。如果8.30再醒来,8.10的任务就来不及了!

所以每次插入新任务的时候,唤醒woeker线程,让worker线程重新获得queue leader元素,看看等待下一个任务多长时间合适。

//简单计时器

公共类TestTimer {

//每个任务实例包含一个要执行的任务

//任务应该放在优先级队列中,但是优先级需要在优先级队列中进行比较。

静态类任务实现ComparableTask{

//什么时候执行?

私人时间长;

//执行什么任务?

私有Runnable命令;

公共任务(Runnable命令,长时间){

this.command=命令;

this . time=system . current time millis()time;

}

公共无效运行(){

//执行Runable中的run方法。

命令. run();

}

@覆盖

公共int compareTo(任务o) {

return(int)(this . time-o . time);

}

}

静态类别计时器{

//首先创建一个优先级阻塞队列

private PriorityBlockingQueueTask queue=new PriorityBlockingQueue();

//使用此对象完成线程间的协调任务

私有对象mei lbox=new Object();

//调度方法是将一个任务放入定时器中。

公共无效计划(Runnable命令,长时间后){

Task task=新任务(命令,之后);

//将当前任务放在相对的列中

queue.put(任务);

//当工作线程包含等待机制时,调度任务时需要唤醒。

同步(meibox){

meibox . notify();

}

}

//编写一个构造函数来创建线程

公共计时器(){

//创建一个线程,让这个线程扫描队列的第一个元素,看是否可以执行。

线程工作线程=新线程(){

@覆盖

公共无效运行(){

//取出队列头的元素,判断这个元素是否可以执行。

while(true){

尝试{

task task=queue . take();

long curr time=system . current time millis();

if(currTime=task.time){

//时间到了,执行任务

task.run()。

}否则{

//时间还没到,继续等

queue.put(任务);

同步(meibox){

mei lbox . wait(task . time-curr time);

}

}

} catch (InterruptedException e) {

e . printstacktrace();

}

}

}

};

worker . start();

}

}

}

测试:

公共静态void main(String[] args) {

Timer Timer=new Timer();

Runnable command=new Runnable() {

@覆盖

公共无效运行(){

System.out.println('时间到了~ ');

//timer.schedule(这个,3000);每3小时执行一次。

}

};

System.out.println('调度任务');

timer.schedule(命令,3000);

}

}

任务安排好之后,等待3s才可以执行。

下面是定时器原生类型中的一些方法。

Schedule (TimerTask task,date time)在指定日期执行一次TimerTask任务。如果日期时间早于当前时间,将立即执行。

Schedule (TimerTask Task,Long Delay,Long Period)以当前时间为基准,延迟指定的毫秒数,然后以指定的时间间隔无限期执行TimerTask任务。

Schedule (TimerTask任务,日期第一次,长周期)在指定日期后的指定时间间隔内无限期执行TimerTask任务。

ScheduleatFixedRate(TimerTask task,long delay,long period)以当前时间为基准,延迟指定的毫秒数,然后以指定的时间间隔周期性地无限执行TimerTask任务。

总结

本文到此为止。希望能帮到你,也希望你能多关注我们的更多内容!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • vue中的定时器清不掉,vue设置定时器调用方法,vue如何设置定时器和清理定时器
  • js定时方法,js的定时器函数
  • js定时方法,js的定时器函数,js定时器的使用(实例讲解)
  • js定时器重复执行怎么停止,js每隔几秒执行一次
  • js定时器重复执行怎么停止,js每隔几秒执行一次,js定时器(执行一次、重复执行)
  • js定时器重复执行怎么停止,,js定时器(执行一次、重复执行)
  • js中2种定时器的使用及清除的实现过程,js中两种定时器的设置及清除
  • js中2种定时器的使用及清除的实现过程,js中两种定时器的设置及清除,JS中2种定时器的使用及清除的实现
  • ,,Qt定时器和随机数详解
  • ,,Qt基础开发之Qt多线程类QThread与Qt定时器类QTimer的详细方法与实例
  • ,,IOS 中NSTimer定时器的使用
  • C语言定时器,c语言定时器程序编写
  • C语言定时器,c语言定时器程序编写,C语言实现简单的定时器
  • java 定时器的多种实现方式有哪些,java定时器的实现方式有几种
  • java 定时器的多种实现方式有哪些,java定时器的实现方式有几种,Java 定时器的多种实现方式
  • 留言与评论(共有 条评论)
       
    验证码: