java多线程定时器Timer的使用详解

时间:2022-06-13 23:33:10

使用过javascript的都知道有两个关于定时的方法:setTimeOut和setInterval方法,可以让一段代码持续性或者规定时间后运行。这样就可以实现定时的功能,最经典的应用就是贪吃蛇那条蛇持续性的走动。这里做一下关于定时器使用的一点小结

定时器:Timer

定时器的任务:TimerTask

 

定时器:Timer

一种工具,线程用其安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行。

有关于定时器定时、任务调度、任务终止等多个api。详细参考java的开发文档


 定时器的任务:TimerTask


TimerTask 的定义知:

public abstract class TimerTask extends Object implements Runnable

它是一个线程。

由构造方法知:创建的是一个定时器任务,相对应于Timer调度的单元

 


案例1:实现隔一段时间后运行一段代码:类似jssetTimeOut函数


以下代码可以贴到main方法中运行

/**

* 1s后boom!相对于js的setTimeOut函数

*/

new Timer().schedule(new TimerTask() {

@Override

public void run() {

System.out.println("boom!");

}

}, 1000);


 

案例2:实现每隔一段时间执行一段代码:类似jssetInterval函数

/**
* 通过方法内部类实现持续性间隔一段时间boom!
*/
class MyTimerTask extends TimerTask{
@Override
public void run() {
System.out.println("booming!");

new Timer().schedule(this, 1000);
}

}

//执行间断性运行
new Timer().schedule(new MyTimerTask(), 1000);


 

运行结果:

booming!

Exception in thread "Timer-1" java.lang.IllegalStateException: Task already scheduled or cancelled

at java.util.Timer.sched(Timer.java:358)

at java.util.Timer.schedule(Timer.java:170)

at cn.mym.timer.TimerTest$1MyTimerTask.run(TimerTest.java:29)

at java.util.TimerThread.mainLoop(Timer.java:512)

at java.util.TimerThread.run(Timer.java:462)

 

 

报错原因:因为定时器的任务已经被使用了一次,所以TimerTask线程已经被调度了就不能被再次使用。就像炸弹一样,爆炸了就不能再爆一次。那么要实现这种功能需要做些改进:即定时器下一次执行的不是this这个自己本身TimerTask,而是一个新的TimerTask

 

/**
* 通过方法内部类实现持续性间隔一段时间boom!
*/
class MyTimerTask extends TimerTask{
@Override
public void run() {
System.out.println("booming!");

new Timer().schedule(new MyTimerTask(), 1000);
}

}

//执行间断性运行
new Timer().schedule(new MyTimerTask(), 1000);


 

即:下一次执行的定时器任务TimerTask是一个新的定时器任务,这样就实现了循环间断

运行如下:

booming!

booming!

booming!

booming!

。。。

 

3.实现间断不同的时间:10002000,交替间断

以上及以下的方法都在main方法中:

本例完整:


public class TimerTest {

static int count = 1;
public static void main(String[] args) {
/**
* 通过方法内部类实现持续性间隔一段时间boom!
*/
class MyTimerTask extends TimerTask{
@Override
/**
* 实现间断不同的时间:1000,2000,交替间断
* 思路:通过一个全局属性来决定本次间断时间1000,还是2000
*/

public void run() {
System.out.println("booming!");
new Timer().schedule(new MyTimerTask(), 1000+1000*count);
count = (++count)%2;//每次的值是1或0
}

}
new Timer().schedule(new MyTimerTask(), 1000);

}
}

运行效果达到!

 



案例小结

那么以上的几种实现:Timer类有相关的调度api,可以翻阅:

 void schedule(TimerTask task, Date time)

          安排在指定的时间执行指定的任务。

 void schedule(TimerTask task, Date firstTime, long period)

          安排指定的任务在指定的时间开始进行重复的固定延迟执行。

 void schedule(TimerTask task, long delay)

          安排在指定延迟后执行指定的任务。

 void schedule(TimerTask task, long delay, long period)

          安排指定的任务从指定的延迟后开始进行重复的固定延迟执行。

 



最后小结

实际工作中可能存在的需求如:每周1-5的晚上10点收邮件,周六日上午10点收邮件,那么就需要用到定时器,如果用TimerTimerTask就比较麻烦。 实际上有一个开源的项目:quartz    提供了关于时间调度的很不错的API



以上为多线程的一点个人总结,后期继续跟上。若有表述不当之处,感谢您的私信指出,我将尽快解决