Timer 和TimerTask分析

Timer 定时器使用举例

大家都知道Timer 可以用来做定时任务,
使用举例,定时5s执行sendPing()逻辑:

Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                sendPing();
            }
        }, 5 * 1000);

Timer 和TimerTask原理分析

  • Timer
    使用规则:

    1. timer 可以定时delay一个时间再执行task,也支持周期性的定时来执行task,schedule(TimerTask task, long delay)和scheduleAtFixedRate(TimerTask task, long delay, long period);

    2. 如果timer 不再需要使用,需要调用cancel()来释放timer的thread和其他资源,如果不这样,timer占用的资源可能长时间得不到释放;

    3. 多线程不需要做同步操作就可以共享一个timer;

原理:
Timer 中有TimerImpl对象,TimerImpl继承自Thread,所以每个Timer 中都有一个thread来顺序执行tasks;

Timer timer = new Timer();源码如下,默认isDaemon是false,启动用户线程;在TimerImpl中就有调用start,说明执行task的线程已经开始启动;

 public Timer(String name, boolean isDaemon) {
        if (name == null) {
            throw new NullPointerException("name == null");
        }
        this.impl = new TimerImpl(name, isDaemon);
        this.finalizer = new FinalizerHelper(impl);
    }

.....
TimerImpl(String name, boolean isDaemon) {
            this.setName(name);
            this.setDaemon(isDaemon);
            this.start();
        }

下面来看看FinalizerHelper这个内部类,
垃圾回收器准备释放内存的时候,会先调用finalize(),那么你可能不知道为什么需要在这里notify线程;

private static final class FinalizerHelper {
        private final TimerImpl impl;
        .....
        @Override protected void finalize() throws Throwable {
            try {
                synchronized (impl) {
                    impl.finished = true;
                    impl.notify();
                }
            } finally {
                super.finalize();
            }
        }
    }

请看TimerImpl 线程的run方法实现:如果不在回收的时候notify,该线程可能会无线循环wait;

public void run() {
            while (true) {
                TimerTask task;
                synchronized (this) {
                    // need to check cancelled inside the synchronized block

                    if (tasks.isEmpty()) {
                        if (finished) {
                            return;
                        }
                        // no tasks scheduled -- sleep until any task appear
                        try {
                            this.wait();
                        } catch (InterruptedException ignored) {
                        }
                        continue;
                    }

                    long currentTime = System.currentTimeMillis();

                    task = tasks.minimum();
                    long timeToSleep;
                   ..........

                        timeToSleep = task.when - currentTime;
                    }
                    //如果需要delay一段时间再执行就先wait
                    if (timeToSleep > 0) {
                        // sleep!
                        try {
                            this.wait(timeToSleep);
                        } catch (InterruptedException ignored) {
                        }
                        continue;
                    }

                    // 如果不需要delay就立即执行
                    synchronized (task.lock) {
                        int pos = 0;
                        if (tasks.minimum().when != task.when) {
                            pos = tasks.getTask(task);
                        }
                        //timertask cancel后从task数组中移除
                        if (task.cancelled) {
                     tasks.delete(tasks.getTask(task));
                            continue;
                        }
                        task.setScheduledTime(task.when);//设置执行的时间

                        // remove task from queue
                        tasks.delete(pos);

                        // 根据是否是周期性执行来判断下一次执行的时间
                        if (task.period >= 0) {
                            // this is a repeating task,
                            if (task.fixedRate) {
                                // task is scheduled at fixed rate
                                task.when = task.when + task.period;
                            } else {
                                // task is scheduled at fixed delay
                                task.when = System.currentTimeMillis()
                                        + task.period;
                            }

                            // insert this task into queue
                            insertTask(task);
                        } else {
                            task.when = 0;
                        }
                    }
                }

            .......
                    task.run();
             .....    
        }
  • TimerTask
    TimerImpl中维护了TimerTask[] timers这个数组,初始大小256;
    当调用schedule或者scheduleAtFixedRate,即有需要执行的task时,都会insertTask()到这个数组;如果执行了,就会从数组中delete(),insert时,会notify当前线程,告诉它开始执行task,就是上面的run();
private void insertTask(TimerTask newTask) {
            // callers are synchronized
            tasks.insert(newTask);
            this.notify();
        }

TimerTask 实现了Runnable接口,所以定时执行的是task.run();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值