Java线程——特殊线程TimerTask定时器

TimerTask是一种特殊的线程,用来为Timer安排一次执行或重复执行的任务。它实现了Runnable接口,是一个抽象类:

/**
 * A task that can be scheduled for one-time or repeated execution by a Timer.
 *
 * @author  Josh Bloch
 * @see     Timer
 * @since   1.3
 */

public abstract class TimerTask implements Runnable{...}

它本身没有实现run()函数,因此需要子类来实现它。所以有了以下的实现方式:

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestTimerTask extends TimerTask {

    @Override
    public void run() {
        System.out.println(new Date());
    }

    public static void main(String[] args) throws InterruptedException {
        Timer timer = new Timer();
        //TimerTask
        TestTimerTask TTT = new TestTimerTask();
        //timer.schedule(TTT, 1000, 1000);
        timer.schedule(TTT, new Date(), 1000);
        Thread.sleep(8000L);
        timer.cancel();
        //创建线程池
        ExecutorService es=Executors.newCachedThreadPool();
    }
}

定时器任务与线程不同,它是定时执行的线程,因此不能够直接使用start()来启动它,而需要使用一个特殊的类Timer来启动它。Timer是一种工具,用来安排在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行。

与每个Timer对象相对应的是单个后台线程,用于顺序地执行所有计时器任务.计时器任务应该迅速完成。如果完成某个计时器任务的时间太长,那么它会“独占”计时器的任务执行线程。因此,这就可能延迟后续任务的执行,而这些任务就可能“堆在一起”,并且在上述不友好的任务最终完成时才能够被快速连续地执行。

对Timer对象最后的引用完成后,并且所有未处理的任务都已执行完成后,计时器的任务执行线程会正常终止(并且成为垃圾回收的对象)。但是这可能要很长时间后才发生。在默认情况下,任
务执行线程并不作为守护线程来运行,所以它能够阻止应用程序终止。如果调用者想要快速终止计时器的任务执行线程,那么调用者应该调用计时器的cancel方法。

public void cancel() {
      ...
    }

如果意外终止了计时器的任务执行线程,例如调用了它的stop方法,那么所有以后对该计时器安排任务的尝试都将导致IllegalStateException,就好像调用了计时器的cancel方法一样。

此类是线程安全的:多个线程可以共享单个Timer对象而无须进行外部同步。此类可扩展到大量同时安排的任务(存在数千个都没有问题)。在内部中,它使用二进制堆来表示其任务队列,所以安排任务的开销是O(logn),其中n是同时安排的任务数。

Timer运行定时器的方式有如下几种。
1、安排在指定的时间执行指定的任务:

 public void schedule(TimerTask task, Date time)

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

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

3、安排在指定延迟后执行指定的任务:

public void schedule(TimerTask task, long delay) 

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

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

5、安排指定的任务在指定的时间开始进行重复的固定速率执行:

 public void scheduleAtFixedRate(TimerTask task, Date firstTime,long period)

6、安排指定的任务在指定的延迟后开始进行重复的固定速率执行:

public void scheduleAtFixedRate(TimerTask task, long delay, long period)

例如,我们可以使用下例循环执行定时器任务,执行的间隔为1000ms:

Timer timer = new Timer();
TestTimerTask TTT = new TestTimerTask();
timer.schedule(TTT, 1000, 1000);

其中的第一个参数1000表示延迟执行的时间,第二个参数表示循环执行的时间,单位均为毫秒(ms)。这样,在系统启动1000ms后才会执行定时器任务,并且每过1000ms都会继续重新执行该任务。程序运行的结果为:

Tue Dec 26 09:53:51 CST 2017
Tue Dec 26 09:53:52 CST 2017
Tue Dec 26 09:53:53 CST 2017
Tue Dec 26 09:53:54 CST 2017
Tue Dec 26 09:53:55 CST 2017
Tue Dec 26 09:53:56 CST 2017
Tue Dec 26 09:53:57 CST 2017
Tue Dec 26 09:53:58 CST 2017
Tue Dec 26 09:53:59 CST 2017
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值