標籤:返回 doc out cancel 停止 計劃 err present public
1.1. 線程池用於定時器
線程池用於定時器調度時,只能指定某個時間段後執行任務,而不能指定具體的時間點。
1.2. 只運行一次的定時器
5秒鐘後運行指定任務的定時器,定時器任務只會被執行1次。
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(3);executorService.schedule( new Runnable(){@Overridepublic void run() {System.out.println("scheduled:" + new Date() + " " + Thread.currentThread().getId());} }, 1000 * 5, TimeUnit.MILLISECONDS );
1.3. 固定比率的定時器
固定比率的定時器會在指定時間段之後首次運行任務,並在之後每隔固定時間段後重複運行任務。以下代碼建立一個5秒後首次運行並每隔1秒重複1次的定時器。
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(3); executorService.scheduleAtFixedRate( new Runnable(){@Overridepublic void run() {System.out.println("scheduled:" + new Date() + " " + Thread.currentThread().getId());} }, 1000 * 5, 1000*1, TimeUnit.MILLISECONDS );
scheduled:Sun Mar 12 19:55:07 CST 2017 8
scheduled:Sun Mar 12 19:55:08 CST 2017 8
scheduled:Sun Mar 12 19:55:09 CST 2017 10
scheduled:Sun Mar 12 19:55:10 CST 2017 10
scheduled:Sun Mar 12 19:55:11 CST 2017 10
scheduled:Sun Mar 12 19:55:12 CST 2017 10
scheduled:Sun Mar 12 19:55:13 CST 2017 11
scheduleAtFixedRate()這個函數的api doc是這樣描述的:
Creates and executes a periodic action that becomes enabled first after the given initial delay, and subsequently with the given period; that is executions will commence after initialDelay then initialDelay+period, then initialDelay + 2 * period, and so on. If any execution of the task encounters an exception, subsequent executions are suppressed. Otherwise, the task will only terminate via cancellation or termination of the executor. If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute.
Parameters:
command the task to execute
initialDelay the time to delay first execution
period the period between successive executions
unit the time unit of the initialDelay and period parameters
Returns:
a ScheduledFuture representing pending completion of the task, and whose get() method will throw an exception upon cancellation
翻譯可能不是很準確,大致的意思就是:
建立和執行一個周期性的動作,這個動作在給定的初始時間延遲之後首次使能,並且以給定的時間間隔持續執行。該動作的執行首次發生於initialDelay個時間單位之後,然後是initialDelay+period,initialDelay + 2*period等等。如果定時任務的任何一次執行發生一個異常,後續執行將被停止。如果沒有發生任何異常,定時任務將直到線程池執行器終止或取消才終止。如果該定時任務的任何一次執行花費的時間長於它的時間間隔(period),那麼後續執行會延遲開始,而不會並存執行。
參數:
command: 待執行的任務。
initialDelay: 初始時間延遲。
period:相鄰的執行之間的時間間隔。
unit: 時間單位。
傳回值:
一個ScheduledFuture對象,用於表達尚未完成的任務。在任務取消時,其get)方法將拋出一個異常。
任務延遲的情況:
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(3); executorService.scheduleAtFixedRate( new Runnable(){@Overridepublic void run() {System.out.println("scheduled:" + new Date() + " " + Thread.currentThread().getId());try {Thread.sleep(1000*3);} catch (InterruptedException e) {e.printStackTrace();}} }, 1000 * 5, 1000*1, TimeUnit.MILLISECONDS );
sleep()導致任務發生延遲,此時任務從每秒執行1次變成了每3秒執行1次。
scheduled:Sun Mar 12 20:55:34 CST 2017 8
scheduled:Sun Mar 12 20:55:37 CST 2017 8
scheduled:Sun Mar 12 20:55:40 CST 2017 10
scheduled:Sun Mar 12 20:55:43 CST 2017 10
scheduled:Sun Mar 12 20:55:46 CST 2017 10
scheduled:Sun Mar 12 20:55:49 CST 2017 10
scheduled:Sun Mar 12 20:55:52 CST 2017 10
scheduled:Sun Mar 12 20:55:55 CST 2017 10
1.4. 固定延時的定時器
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(3); executorService.scheduleWithFixedDelay( new Runnable(){@Overridepublic void run() {System.out.println("scheduled:" + new Date() + " " + Thread.currentThread().getId()); } }, 1000 * 5, 1000*1, TimeUnit.MILLISECONDS );
scheduled:Sun Mar 12 20:51:29 CST 2017 8
scheduled:Sun Mar 12 20:51:30 CST 2017 8
scheduled:Sun Mar 12 20:51:31 CST 2017 10
scheduled:Sun Mar 12 20:51:32 CST 2017 10
scheduled:Sun Mar 12 20:51:33 CST 2017 10
scheduled:Sun Mar 12 20:51:34 CST 2017 10
scheduled:Sun Mar 12 20:51:35 CST 2017 10
scheduled:Sun Mar 12 20:51:36 CST 2017 10
scheduled:Sun Mar 12 20:51:37 CST 2017 11
scheduled:Sun Mar 12 20:51:38 CST 2017 11
任務被延遲的情況:
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(3); executorService.scheduleWithFixedDelay( new Runnable(){@Overridepublic void run() {System.out.println("scheduled:" + new Date() + " " + Thread.currentThread().getId());try {Thread.sleep(1000*3);} catch (InterruptedException e) {e.printStackTrace();}} }, 1000 * 5, 1000*1, TimeUnit.MILLISECONDS );
原來計劃每秒執行1次的任務,變成了每4秒執行1次。後續延時周期跟固定比率定時器有差異。固定比率變成了3秒,而固定延時變成了4秒。
固定比率可以理解為前面任務結束後發現執行時間已經超過了延時間隔周期就不在等待而是立即開始執行後續任務。 固定延時可以理解為前面任務完成之後開始正常計算後續任務的延時。
scheduled:Sun Mar 12 20:35:44 CST 2017 8
scheduled:Sun Mar 12 20:35:48 CST 2017 8
scheduled:Sun Mar 12 20:35:52 CST 2017 10
scheduled:Sun Mar 12 20:35:56 CST 2017 10
scheduled:Sun Mar 12 20:36:00 CST 2017 10
scheduled:Sun Mar 12 20:36:04 CST 2017 10
scheduled:Sun Mar 12 20:36:08 CST 2017 10
scheduled:Sun Mar 12 20:36:12 CST 2017 10
scheduled:Sun Mar 12 20:36:16 CST 2017 10
scheduled:Sun Mar 12 20:36:20 CST 2017 10
scheduled:Sun Mar 12 20:36:24 CST 2017 10
scheduled:Sun Mar 12 20:36:28 CST 2017 10
scheduled:Sun Mar 12 20:36:32 CST 2017 10
scheduled:Sun Mar 12 20:36:36 CST 2017 10
Java並發程式設計(8)線程池之用於定時器