ScheduledThreadPoolExecutor淺析

  • ScheduledThreadPoolExecutor繼承自ThreadPoolExecutor。它主要用來在給定的延遲之后執(zhí)行任務(wù),或者定期執(zhí)行任務(wù)。
  • ScheduledThreadPoolExecutor的功能與Timer類似炮车,但比Timer更強(qiáng)大,更靈活,Timer對應(yīng)的是單個(gè)后臺線程瘦穆,而ScheduledThreadPoolExecutor可以在構(gòu)造函數(shù)中指定多個(gè)對應(yīng)的后臺線程數(shù)纪隙。

1 創(chuàng)建ScheduledThreadPoolExecutor

  • ScheduledThreadPoolExecutor通常使用工廠類Executors來創(chuàng)建,Executors可以創(chuàng)建兩種類型的ScheduledThreadPoolExecutor扛或,如下:
  • (1)ScheduledThreadPoolExecutor:可以執(zhí)行并行任務(wù)也就是多條線程同時(shí)執(zhí)行绵咱。
  • (2)SingleThreadScheduledExecutor:可以執(zhí)行單條線程。

1.1 ScheduledThreadPoolExecutor

創(chuàng)建ScheduledThreadPoolExecutor的方法構(gòu)造如下:

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory)

1.2 SingleThreadScheduledExecutor

創(chuàng)建SingleThreadScheduledExecutor的方法構(gòu)造如下:

public static ScheduledExecutorService newSingleThreadScheduledExecutor()
public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory)

1.3 創(chuàng)建實(shí)例對象

創(chuàng)建實(shí)例對象代碼如下

ScheduledExecutorService scheduledThreadPoolExecutor=Executors.newScheduledThreadPool(5);

ScheduledExecutorService singleThreadScheduledExecutor=Executors.newSingleThreadScheduledExecutor();

2 ScheduledThreadPoolExecutor執(zhí)行機(jī)制分析

6b67d1561cfaa41a82514ca8b29056ed.png

分析:DelayQueue是一個(gè)無界隊(duì)列告喊,所以ThreadPoolExecutor的maximumPoolSize在ScheduledThreadPoolExecutor中無意義麸拄。
ScheduledThreadPoolExecutor的執(zhí)行主要分為以下兩個(gè)部分

  • (1)當(dāng)調(diào)用ScheduledThreadPoolExecutor的scheduleAtFixedRate()方法或者scheduleWithFixedDelay()方法時(shí),會向ScheduledThreadPoolExecutor的DelayQueue添加一個(gè)實(shí)現(xiàn)了RunnableScheduledFuture接口的ScheduleFutureTask黔姜。
  • (2)線程池中的線程從DelayQueue中獲取ScheduleFutureTask拢切,然后執(zhí)行任務(wù)。

3 使用場景

3.1 ScheduledThreadPoolExecutor和SingleThreadScheduledExecutor的適用場景

  • ScheduledThreadPoolExecutor:適用于多個(gè)后臺線程執(zhí)行周期性任務(wù)秆吵,同時(shí)為了滿足資源管理的需求而需要限制后臺線程數(shù)量的應(yīng)用場景淮椰。
  • SingleThreadScheduledExecutor:適用于需要單個(gè)后臺線程執(zhí)行周期任務(wù),同時(shí)需要保證任務(wù)順序執(zhí)行的應(yīng)用場景纳寂。

4 ScheduledThreadPoolExecutor使用案例

我們創(chuàng)建一個(gè)Runnable的對象主穗,然后使用ScheduledThreadPoolExecutor的Scheduled()來執(zhí)行延遲任務(wù),輸出執(zhí)行時(shí)間即可:

4.1 該類延遲執(zhí)行的方法:

public ScheduledFuture schedule(Runnable command,long delay, TimeUnit unit);

參數(shù)解析:

  • command:就是一個(gè)實(shí)現(xiàn)Runnable接口的類
  • delay:延遲多久后執(zhí)行毙芜。
  • unit:用于指定keepAliveTime參數(shù)的時(shí)間單位忽媒,這是一個(gè)枚舉,常用的有TimeUnit.MILLISECONDS(毫秒)腋粥,TimeUnit.SECONDS(秒)以及TimeUnit.MINUTES(分鐘)等晦雨。
    schedule
//創(chuàng)建一個(gè)工作線程繼承Runnable
public class WorkerThread implements Runnable{
  @Override
  public void run() {
     System.out.println(Thread.currentThread().getName()+" Start. Time = "+getNowDate());
       threadSleep();
       System.out.println(Thread.currentThread().getName()+" End. Time = "+getNowDate());
    
  }
  /**
   * 睡3秒
   */
  public void threadSleep(){
    try {
      Thread.sleep(3000);
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
   /**
    * 獲取現(xiàn)在時(shí)間
    * 
    * @return 返回時(shí)間類型 yyyy-MM-dd HH:mm:ss
    */
  public static String getNowDate() {
      Date currentTime = new Date();
      SimpleDateFormat formatter; 
        formatter = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss"); 
        String ctime = formatter.format(currentTime); 
      return ctime;
     }
}
public class ScheduledThreadPoolTest {
  
  public static void main(String[] args) {
    ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
     try {
      //schedule to run after sometime
      System.out.println("Current Time = "+getNowDate());
      for(int i=0; i<3; i++){
          Thread.sleep(1000);
          WorkerThread worker = new WorkerThread();
          //延遲5秒后執(zhí)行
          scheduledThreadPool.schedule(worker, 10, TimeUnit.SECONDS);
      }
      Thread.sleep(3000);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
      scheduledThreadPool.shutdown();
      while(!scheduledThreadPool.isTerminated()){
          //wait for all tasks to finish
      }
      System.out.println("Finished all threads");
  }
  
   /**
    * 獲取現(xiàn)在時(shí)間
    * 
    * @return 返回時(shí)間類型 yyyy-MM-dd HH:mm:ss
    */
   public static String getNowDate() {
    Date currentTime = new Date();
    SimpleDateFormat formatter; 
      formatter = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss"); 
      String ctime = formatter.format(currentTime); 
    return ctime;
   }
}
9cc165d7ac247dbceff5524eb7faf2d8.png

線程任務(wù)確實(shí)在10秒延遲后才開始執(zhí)行。這就是schedule()方法的使用隘冲。
** scheduleAtFixedRate**

public ScheduledFuture scheduleAtFixedRate(Runnable command,long initialDelay,long period,TimeUnit unit)

scheduleAtFixedRate方法的作用是預(yù)定在初始的延遲結(jié)束后闹瞧,周期性地執(zhí)行給定的任務(wù),周期長度為period展辞,其中initialDelay為初始延遲奥邮。

scheduleWithFixedDelay

public ScheduledFuture scheduleWithFixedDelay(Runnable command,long initialDelay,long delay,TimeUnit unit);

scheduleWithFixedDelay方法的作用是預(yù)定在初始的延遲結(jié)束后周期性地執(zhí)行給定任務(wù),在一次調(diào)用完成和下一次調(diào)用開始之間有長度為delay的延遲罗珍,其中initialDelay為初始延遲洽腺。
案例代碼

//周期函數(shù)測試類
public class ScheduledTask {
  public ScheduledThreadPoolExecutor se = new ScheduledThreadPoolExecutor(5);
  public static void main(String[] args) {
    new ScheduledTask();
  }
  public void fixedPeriodSchedule() {
    // 設(shè)定可以循環(huán)執(zhí)行的runnable,初始延遲為0,這里設(shè)置的任務(wù)的間隔為1秒
    for(int i=0;i<5;i++){
      se.scheduleAtFixedRate(new FixedSchedule(), 0, 1, TimeUnit.SECONDS);
    }
  }
  public ScheduledTask() {
    fixedPeriodSchedule();
  }
  class FixedSchedule implements Runnable {
    public void run() {
      System.out.println("當(dāng)前線程:"+Thread.currentThread().getName()+"  當(dāng)前時(shí)間:"+new Date(System.currentTimeMillis()));
    }
  }
}

SingleThreadScheduledExecutor的使用的方法基本是類似

cankao

https://juejin.im/entry/57ad83932e958a005442862c

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末靡砌,一起剝皮案震驚了整個(gè)濱河市已脓,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌通殃,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異画舌,居然都是意外死亡堕担,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進(jìn)店門曲聂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來霹购,“玉大人,你說我怎么就攤上這事朋腋∑敫恚” “怎么了?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵旭咽,是天一觀的道長贞奋。 經(jīng)常有香客問我,道長穷绵,這世上最難降的妖魔是什么轿塔? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮仲墨,結(jié)果婚禮上勾缭,老公的妹妹穿的比我還像新娘。我一直安慰自己目养,他們只是感情好俩由,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著癌蚁,像睡著了一般幻梯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上匈勋,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天礼旅,我揣著相機(jī)與錄音,去河邊找鬼洽洁。 笑死痘系,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的饿自。 我是一名探鬼主播汰翠,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼昭雌!你這毒婦竟也來了复唤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤烛卧,失蹤者是張志新(化名)和其女友劉穎佛纫,沒想到半個(gè)月后妓局,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡呈宇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年好爬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片甥啄。...
    茶點(diǎn)故事閱讀 38,626評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡存炮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蜈漓,到底是詐尸還是另有隱情穆桂,我是刑警寧澤,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布融虽,位于F島的核電站享完,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏衣形。R本人自食惡果不足惜驼侠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望谆吴。 院中可真熱鬧倒源,春花似錦、人聲如沸句狼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽腻菇。三九已至胳螟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間筹吐,已是汗流浹背糖耸。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留丘薛,地道東北人嘉竟。 一個(gè)月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像洋侨,于是被迫代替她去往敵國和親舍扰。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 寫在最前 本次嘗試淺析Node.js中的EventEmitter模塊的事件機(jī)制希坚,分析在Node.js中實(shí)現(xiàn)發(fā)布訂閱...
    Annnnnn閱讀 1,332評論 0 1
  • 纏論中關(guān)于背馳和MACD的邏輯關(guān)系解說可謂是多如牛毛边苹。在這里沒有解盤的圖片,只有邏輯解析和思考的一些想法...
    叁三弎閱讀 1,136評論 2 8
  • 1 為什么需要線程池裁僧? 1.在java中个束,使用線程來執(zhí)行異步任務(wù)時(shí)慕购,線程的創(chuàng)建和銷毀需要一定的開銷。如果我們?yōu)槊恳?..
    凱玲之戀閱讀 826評論 0 1
  • 一直以來我都比較喜歡的播急,就是安靜的做自己喜歡的事情 脓钾,喜歡書售睹,喜歡登山桩警,喜歡極限運(yùn)動(dòng)。 今天分享的主題也是與書有關(guān)...
    sammi曠閱讀 490評論 0 0
  • 各位老師昌妹,各位家長捶枢,各位同學(xué): 你們好!我是馮杰的媽媽飞崖,感謝兒子的努力烂叔,受班主任委托,很榮幸作為家長代表站...
    相洪2018閱讀 894評論 0 1