任务调度(三)——Timer的替代品ScheduledExecutorService简介
轉(zhuǎn)載自??任務(wù)調(diào)度(三)——Timer的替代品ScheduledExecutorService簡(jiǎn)介
? ?先前的兩篇博文《任務(wù)調(diào)度(一)——jdk自帶的Timer》和《任務(wù)調(diào)度(二)——jdk自帶的Timer 動(dòng)態(tài)修改任務(wù)執(zhí)行計(jì)劃》中,簡(jiǎn)單介紹了一下Timer,可以實(shí)現(xiàn)幾本的功能,但是在多線(xiàn)程方面卻略顯不足。
? ? ? ?根據(jù)Timer源碼,可以看到Timer是單線(xiàn)程的。所以task都是串行執(zhí)行。假如其中一個(gè)task執(zhí)行需要很長(zhǎng)的時(shí)間,那其他的task只能干巴巴的等著。怎么辦!
? ? ? 現(xiàn)在就遇到了這樣的問(wèn)題。總不能因?yàn)檫@個(gè)小小的問(wèn)題就去換別的任務(wù)調(diào)度框架吧,還是想用最簡(jiǎn)單的方案去解決一下。所以ScheduledExecutorService就被我選中了。這個(gè)是怎么找到的?1.網(wǎng)上搜,2.好好的看Timer類(lèi)的注釋:
? ? ? ?翻譯一下:java5.0引入了java.util.concurrent包,其中java.util.concurrent.scheduledthreadpoolexecutor就是在并發(fā)實(shí)用工具其中之一。scheduledthreadpoolexecutor是一個(gè)可以重復(fù)執(zhí)行任務(wù)的線(xiàn)程池,并且可以指定任務(wù)的間隔和延遲時(shí)間。它作為比Timer/TimerTask更加通用的替代品。因?yàn)樗试S多個(gè)服務(wù)線(xiàn)程,接受不同的時(shí)間單位,且不需要繼承TimeTask(僅僅需要實(shí)現(xiàn)Runnable接口)。配置ScheduledThreadPoolExecutor為單線(xiàn)程,則與使用Timer等效。
? ? ? ?ScheduledThreadPoolExecutor實(shí)現(xiàn)了ScheduledExecutorService接口,所以標(biāo)題中使用了接口的名字。
? ? ? ?ScheduledExecutorService提供了4個(gè)方法:
? ? ? ?其中第二個(gè)方法比較特殊一點(diǎn),第一個(gè)參數(shù)是Callable,別的都是Runnable,二者的區(qū)別不再這篇博文的討論范圍之內(nèi)。就此略過(guò)。說(shuō)一些其他三個(gè)方法。
? ? ? ?schedule()方法第一個(gè)參數(shù)是任務(wù)實(shí)例,第二個(gè)參數(shù)是延遲時(shí)間,第三個(gè)是時(shí)間單元。比如調(diào)用如下:
ScheduledExecutorService pool = Executors.newScheduledThreadPool(2); pool.schedule(task1, 5, TimeUnit.SECONDS);//延遲5s后,執(zhí)行且只執(zhí)行一次task1? ? ? ?scheduleAtFixedRate()和scheduleWithFixedDelay方法參數(shù)是一樣的。第一個(gè)參數(shù)是任務(wù)實(shí)例,第二個(gè)參數(shù)是延遲時(shí)間,第三個(gè)是間隔時(shí)間,第四個(gè)是時(shí)間單元。這兩個(gè)方法的不同之處在方法名也能看得出來(lái):scheduleAtFixedRate方法是按照固定頻率去執(zhí)行任務(wù)的。而scheduleWithFixedDelay方法則是按照固定的延遲去執(zhí)行任務(wù)。
/** * 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()); } }測(cè)試scheduleAtFixedRate方法:
public static void main(String[] args) { ScheduledExecutorService pool = Executors.newScheduledThreadPool(1); Task1 t1 = new Task1(); //立即執(zhí)行t1,3s后任務(wù)結(jié)束,再等待2s(間隔時(shí)間-消耗時(shí)間),如果有空余線(xiàn)程時(shí),再次執(zhí)行該任務(wù) pool.scheduleAtFixedRate(t1, 0, 5, TimeUnit.SECONDS); }執(zhí)行結(jié)果如圖:
? ? ? ?task1第二次執(zhí)行的前提是,當(dāng)前有空余的線(xiàn)程。
? ? ? ?執(zhí)行的開(kāi)始時(shí)間則是上一次結(jié)束時(shí)間+(間隔時(shí)間-任務(wù)消耗的時(shí)間)。加入這個(gè)差值小于0,即間隔時(shí)間小于任務(wù)消耗的時(shí)間,那就不會(huì)再等待,會(huì)立即執(zhí)行(當(dāng)然得滿(mǎn)足前提)。
測(cè)試scheduleAtFixedRate方法:
public static void main(String[] args) { ScheduledExecutorService pool = Executors.newScheduledThreadPool(1); Task1 t1 = new Task1(); //立即執(zhí)行t1,3s后任務(wù)結(jié)束,再等待5s(間隔時(shí)間-消耗時(shí)間),如果有空余線(xiàn)程時(shí),再次執(zhí)行該任務(wù) pool.scheduleWithFixedDelay(t1, 0, 5, TimeUnit.SECONDS); }? ? ? ?執(zhí)行結(jié)果如圖:
? ? ? ?就簡(jiǎn)單介紹到這里,下篇將會(huì)分享替換Timer的代碼。
總結(jié)
以上是生活随笔為你收集整理的任务调度(三)——Timer的替代品ScheduledExecutorService简介的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 周四英语怎么读 周四的英语单词是什么
- 下一篇: 画画英文怎么写 画画的英文是什么