Java多线程-定时器Timer

Timer执行不结束

public class MyTask extends TimerTask {
    public void run() {
        System.out.println("运行了代码");
    }
}

//延迟5000毫秒后执行
Timer timer=new Timer();
timer.schedule(new MyTask(),5000);

我们发现他执行了一次MyTask后,线程未关闭,查询源码发现,他内部有一个Thread,run方法设置为while(true)因此,他不会关闭。如果需要和Thread一样执行完成就关闭,可以在task的run方法里面执行timer.cancel。

当mainLoop抛出任何异常时,线程将结束并将任务队列清空退出

public void run() {
        try {
            mainLoop();
        } finally {
            // Someone killed this Thread, behave as if Timer cancelled
            synchronized(queue) {
                newTasksMayBeScheduled = false;
                queue.clear();  // Eliminate obsolete references
            }
        }
    }

 private void mainLoop() {
        while (true) {
            ......
        }
    }

Timer执行延迟

由于TimerTask是以队列的方法一个一个被顺序执行,所以执行的时间有可能和预期的时间不一致,因为前面的任务有可能消耗的时间比较长,则后面的时间会被延迟

Timer的api

//延迟delay毫秒后,执行一次
schedule(TimerTask task, long delay)

//延迟到time时间开始,执行一次
schedule(TimerTask task, Date time)

//延迟delay毫秒后,每period执行一次
//按照顺序执行,不会有非线程安全问题
//前一个任务执行时间长,则后面的任务也会延迟执行,按照前一个任务执行结束的时间+period
schedule(TimerTask task, long delay, long period)

//从time时间开始,每period执行一次
//time时间早于当前时间,立即执行
//按照顺序执行,不会有非线程安全问题
//前一个任务执行时间长,则后面的任务也会延迟执行,按照前一个任务执行结束的时间+period
schedule(TimerTask task, Date time, long period)

//延迟delay毫秒后,每period执行一次
//按照顺序执行,不会有非线程安全问题
//固定频率,不会因为前一个任务执行时间长而是后一个任务延迟执行
scheduleAtFixedRate(TimerTask task, long delay, long period)

//从time时间开始,每period执行一次
//按照顺序执行,不会有非线程安全问题
//time时间早于当前时间,立即执行
//固定频率,不会因为前一个任务执行时间长而是后一个任务延迟执行
scheduleAtFixedRate(TimerTask task, Date firstTime, long period)

//将任务队列的全部任务清空,任务销毁
//有时他不能立即停止,看源码,他执行cancel的时候需要拿到queue锁,当他无法拿到的时候,就需要等待
//public void cancel() {
//        synchronized(queue) {
//             thread.newTasksMayBeScheduled = false;
//             queue.clear();
//             queue.notify();  // In case queue was already empty.
//         }
//     }
cancel();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值