复制代码
看看这个内部变量thread:
1 /**
2 * The timer thread.
3 */
4 private TimerThread thread = new TimerThread(queue);
不是原生的Thread,是自定义的类TimerThread.这个类实现了Thread类,重写了run方法,如下:
复制代码
1 public void run() {
2 try {
3 mainLoop();
4 } finally {
5 // Someone killed this Thread, behave as if Timer cancelled
6 synchronized(queue) {
7 newTasksMayBeScheduled = false;
8 queue.clear(); // Eliminate obsolete references
9 }
10 }
11 }
复制代码
最后是这个mainLoop方法,这方法比较长,截取开头一段:
复制代码
1 private void mainLoop() {
2 while (true) {
3 try {
4 TimerTask task;
5 boolean taskFired;
6 synchronized(queue) {
7 // Wait for queue to become non-empty
8 while (queue.isEmpty() && newTasksMayBeScheduled)
9 queue.wait();
10 if (queue.isEmpty())
11 break; // Queue is empty and will forever remain; die
复制代码
可以看到wait方法,之前的notify就是通知到这个wait,然后clear方法在notify之前做了清空数组的操作,所以会break,线程执行结束,退出。
5. 反复执行一个任务
通过调用三个参数的schedule方法实现,最后一个参数是执行间隔,单位毫秒。
6. schedule VS. scheduleAtFixedRate
这两个方法都是任务调度方法,他们之间区别是,schedule会保证任务的间隔是按照定义的period参数严格执行的,如果某一次调度时间比较长,那么后面的时间会顺延,保证调度间隔都是period,而scheduleAtFixedRate是严格按照调度时间来的,如果某次调度时间太长了,那么会通过缩短间隔的方式保证下一次调度在预定时间执行。举个栗子:你每个3秒调度一次,那么正常就是0,3,6,9s这样的时间,如果第二次调度花了2s的时间,如果是schedule,就会变成0,3+2,8,11这样的时间,保证间隔,而scheduleAtFixedRate就会变成0,3+2,6,9,压缩间隔,保证调度时间。
7. 一些注意点
每一个Timer仅对应唯一一个线程。
Timer不保证任务执行的十分精确。
Timer类的线程安全的。