Timer源码分析.docx
文本预览下载声明
Timer源码解析Timer是java.util包下的类,里面包含了两个成员变量,一个是TaskQueue,它是一个初始长度为128的TimerTask的数组(当add时长度等于数组的长度时,数组的长度会扩大一倍),用来存放TimerTask。另一个是TimerThread,它继承了Thread,用来执行TaskQueue中的TimerTask。说到里面大家也可以大概了解Timer的工作原理了。根据测试代码来分析:public class TimerTest {public static Timer timer = new Timer();public static void testDoSubmit(TimerTask timerTest,int delay,int period){timer.schedule(timerTest, delay, period);}}new Timer()创建timer对象时启动TimerThred线程。当调用timer.schedule的方法时,就是将TimeTask放入TaskQueue中。TimerThred的run方法就会从队列中取出TimeTask,并执行TimeTask的run方法。说了大概的原理,我们来看源码中是如何写的:首先介绍sched方法private void sched(TimerTask task, long time, long period) { if (time 0) throw new IllegalArgumentException(Illegal execution time.); synchronized(queue) { if (!thread.newTasksMayBeScheduled) throw new IllegalStateException(Timer already cancelled.);//timer被cancel了thread.newTasksMayBeScheduled = false。 synchronized(task.lock) { if (task.state != TimerTask.VIRGIN) throw new IllegalStateException( Task already scheduled or cancelled); task.nextExecutionTime = time;//设置执行的时间 task.period = period;//设置时间间隔 task.state = TimerTask.SCHEDULED;//设置任务状态 }//对task属性设置 queue.add(task);//将任务放入队列中 if (queue.getM queue.add(task);in() == task) queue.notify();//如果放入的这个任务是目前队列的第一个,队列将被唤醒 }}在queue.add(task)时,add的方法内部会给任务排序,会将最先执行的任务放在队头,保证每次getMin出来的任务是最先要执行的,尽量减少误差。当add到queue,这个任务不会马上执行,只是放进了queue中,那task又是在什么时候执行的呢。我们前面提到了:new Timer()创建timer对象时启动TimerThred线程。就是在这个处理每个任务的。public void run() { try { mainLoop(); } finally { // Someone killed this Thread, behave as if Timer cancelled synchronized(queue) { newTasksMayBeScheduled = false; queue.clear(); // Eliminate obsolete references } }}这是TimerThred的run方法。主要逻辑都在mainLoop()中,private void mainLoop() { while (true) { try { TimerTask task; boolean taskFired; synchronized(queue) { // Wait for queue to become non-empty while (queue.isEmpty() newTasksMayBeScheduled) queue.wait();//等到queue被唤醒 if (queue.isEmpty()) break; // Queue is empty and will forever remain; die // Queue nonempty; look at first ev
显示全部