任务调度(三)——Timer的替代品ScheduledExecutorService简介
轉載自??任務調度(三)——Timer的替代品ScheduledExecutorService簡介
? ?先前的兩篇博文《任務調度(一)——jdk自帶的Timer》和《任務調度(二)——jdk自帶的Timer 動態修改任務執行計劃》中,簡單介紹了一下Timer,可以實現幾本的功能,但是在多線程方面卻略顯不足。
? ? ? ?根據Timer源碼,可以看到Timer是單線程的。所以task都是串行執行。假如其中一個task執行需要很長的時間,那其他的task只能干巴巴的等著。怎么辦!
? ? ? 現在就遇到了這樣的問題。總不能因為這個小小的問題就去換別的任務調度框架吧,還是想用最簡單的方案去解決一下。所以ScheduledExecutorService就被我選中了。這個是怎么找到的?1.網上搜,2.好好的看Timer類的注釋:
? ? ? ?翻譯一下:java5.0引入了java.util.concurrent包,其中java.util.concurrent.scheduledthreadpoolexecutor就是在并發實用工具其中之一。scheduledthreadpoolexecutor是一個可以重復執行任務的線程池,并且可以指定任務的間隔和延遲時間。它作為比Timer/TimerTask更加通用的替代品。因為它允許多個服務線程,接受不同的時間單位,且不需要繼承TimeTask(僅僅需要實現Runnable接口)。配置ScheduledThreadPoolExecutor為單線程,則與使用Timer等效。
? ? ? ?ScheduledThreadPoolExecutor實現了ScheduledExecutorService接口,所以標題中使用了接口的名字。
? ? ? ?ScheduledExecutorService提供了4個方法:
? ? ? ?其中第二個方法比較特殊一點,第一個參數是Callable,別的都是Runnable,二者的區別不再這篇博文的討論范圍之內。就此略過。說一些其他三個方法。
? ? ? ?schedule()方法第一個參數是任務實例,第二個參數是延遲時間,第三個是時間單元。比如調用如下:
ScheduledExecutorService pool = Executors.newScheduledThreadPool(2); pool.schedule(task1, 5, TimeUnit.SECONDS);//延遲5s后,執行且只執行一次task1? ? ? ?scheduleAtFixedRate()和scheduleWithFixedDelay方法參數是一樣的。第一個參數是任務實例,第二個參數是延遲時間,第三個是間隔時間,第四個是時間單元。這兩個方法的不同之處在方法名也能看得出來:scheduleAtFixedRate方法是按照固定頻率去執行任務的。而scheduleWithFixedDelay方法則是按照固定的延遲去執行任務。
/** * task1 * * @author arron * @date 2015年8月5日 下午2:08:34 * @version 1.0 */ public class Task1 implements Runnable{ @SuppressWarnings("deprecation") public void run() { System.out.println("----task1 start--------"+new Date().toLocaleString()); try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("----3s later, task1 end--------"+new Date().toLocaleString()); } }測試scheduleAtFixedRate方法:
public static void main(String[] args) { ScheduledExecutorService pool = Executors.newScheduledThreadPool(1); Task1 t1 = new Task1(); //立即執行t1,3s后任務結束,再等待2s(間隔時間-消耗時間),如果有空余線程時,再次執行該任務 pool.scheduleAtFixedRate(t1, 0, 5, TimeUnit.SECONDS); }執行結果如圖:
? ? ? ?task1第二次執行的前提是,當前有空余的線程。
? ? ? ?執行的開始時間則是上一次結束時間+(間隔時間-任務消耗的時間)。加入這個差值小于0,即間隔時間小于任務消耗的時間,那就不會再等待,會立即執行(當然得滿足前提)。
測試scheduleAtFixedRate方法:
public static void main(String[] args) { ScheduledExecutorService pool = Executors.newScheduledThreadPool(1); Task1 t1 = new Task1(); //立即執行t1,3s后任務結束,再等待5s(間隔時間-消耗時間),如果有空余線程時,再次執行該任務 pool.scheduleWithFixedDelay(t1, 0, 5, TimeUnit.SECONDS); }? ? ? ?執行結果如圖:
? ? ? ?就簡單介紹到這里,下篇將會分享替換Timer的代碼。
總結
以上是生活随笔為你收集整理的任务调度(三)——Timer的替代品ScheduledExecutorService简介的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 周四英语怎么读 周四的英语单词是什么
- 下一篇: 聊聊并发(八)——Fork/Join框架