欢迎来到天天文库
浏览记录
ID:38254865
大小:22.18 KB
页数:4页
时间:2019-06-07
《Timer源码分析》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、1、Timer源码解析Timer是java.util包下的类,里面包含了两个成员变量,一个是TaskQueue,它是一个初始长度为128的TimerTask的数组(当add时长度等于数组的长度时,数组的长度会扩大一倍),用来存放TimerTask。另一个是TimerThread,它继承了Thread,用来执行TaskQueue中的TimerTask。说到里面大家也可以大概了解Timer的工作原理了。根据测试代码来分析:publicclassTimerTest{publicstaticTimertim
2、er=newTimer();publicstaticvoidtestDoSubmit(TimerTasktimerTest,intdelay,intperiod){timer.schedule(timerTest,delay,period);}}newTimer()创建timer对象时启动TimerThred线程。当调用timer.schedule的方法时,就是将TimeTask放入TaskQueue中。TimerThred的run方法就会从队列中取出TimeTask,并执行TimeTask的run
3、方法。说了大概的原理,我们来看源码中是如何写的:首先介绍sched方法privatevoidsched(TimerTasktask,longtime,longperiod){if(time<0)thrownewIllegalArgumentException("Illegalexecutiontime.");synchronized(queue){if(!thread.newTasksMayBeScheduled)thrownewIllegalStateException("Timeralready
4、cancelled.");//timer被cancel了thread.newTasksMayBeScheduled=false。synchronized(task.lock){if(task.state!=TimerTask.VIRGIN)thrownewIllegalStateException("Taskalreadyscheduledorcancelled");task.nextExecutionTime=time;//设置执行的时间task.period=period;//设置时间间隔tas
5、k.state=TimerTask.SCHEDULED;//设置任务状态}//对task属性设置queue.add(task);//将任务放入队列中if(queue.getMqueue.add(task);in()==task)queue.notify();//如果放入的这个任务是目前队列的第一个,队列将被唤醒}}在queue.add(task)时,add的方法内部会给任务排序,会将最先执行的任务放在队头,保证每次getMin出来的任务是最先要执行的,尽量减少误差。当add到queue,这个任务不会
6、马上执行,只是放进了queue中,那task又是在什么时候执行的呢。我们前面提到了:newTimer()创建timer对象时启动TimerThred线程。就是在这个处理每个任务的。publicvoidrun(){try{mainLoop();}finally{//SomeonekilledthisThread,behaveasifTimercancelledsynchronized(queue){newTasksMayBeScheduled=false;queue.clear();//Elimina
7、teobsoletereferences}}}这是TimerThred的run方法。主要逻辑都在mainLoop()中,privatevoidmainLoop(){while(true){try{TimerTasktask;booleantaskFired;synchronized(queue){//Waitforqueuetobecomenon-emptywhile(queue.isEmpty()&&newTasksMayBeScheduled)queue.wait();//等到queue被唤醒i
8、f(queue.isEmpty())break;//Queueisemptyandwillforeverremain;die//Queuenonempty;lookatfirstevtanddotherightthinglongcurrentTime,executionTime;task=queue.getMin();//取队列的第一个synchronized(task.lock){if(task.state==TimerTask.CANCELLED){queue.r
此文档下载收益归作者所有