java ExecutorService 線程池

最近在做項目時,需要用到線程池。

我不喜歡一開始上來就講底層,因爲這樣子很深奧。

對於線程池,java jdk 1.7裏會有對應的接口ExecutorService與實現類newCachedThreadPool /newFixedThreadPool /newScheduledThreadPool 。

這篇博客裏推薦新手先看看,因爲如果只關注怎麼用,先不扔源碼的話,是夠用的。《java ExecutorService

newCachedThreadPool :可緩存,也就是他會利用已經運行完畢的線程,比如線程池裏有A、B兩個線程,如果現在又來一個請求C。如果線程A現在是空閒的,則可以用線程A來接受請求C,而不用再去new一個線程。

 newFixedThreadPool :定長的線程池。也就是池裏的最大線程數是固定的。

  • 如果你的線程池容量爲10,線程池裏有A、B兩個線程。如果現在又來一個請求C,他是不會檢查之前的線程進行復用。而是會創建一個新的線程C來接收請求C。
  • 如果當前線程池裏已經有10個線程,這時候又來一個新的請求。此時纔會去檢查池裏是否有空閒的線程,如果有的話就利用舊的空閒線程去接收請求。如果沒有的話就放在等待隊列裏。而且直到線程池shutDown(),否則線程池裏的線程是沒有辦法在內存裏釋放的
  • 需要注意的是,newFixedThreadPool的源碼裏的等待隊列使用的是 LinkedBlockingQueue<Runnable>()。當等待隊列是LinkedBlockingQueue的時候,所以該線程池的第二個初始化參數public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime, TimeUnit unit,BlockingQueue<Runnable> workQueue)是無效的。所以如果直接ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3)這樣子建議線程池,則只是確認了第一個參數corePoolSize。第二個參數maximumPoolSize雖然被設置,但是沒有實際效果。如果超過corePoolSize,會全部加到阻塞隊列裏面去。

newScheduledThreadPool :用於定時任務或週期性任務執行。


如果你不想使用上面那些,可以自定義線程池,如下:

ThreadPoolExecutor pool = new ThreadPoolExecutor(1, 2, 2, TimeUnit.HOURS, new LinkedBlockingQueue<Runnable>());

參數的含義分別爲:【引用:Java多線程-線程池ThreadPoolExecutor構造方法和規則

  • corePoolSize

    核心線程數,默認情況下核心線程會一直存活,即使處於閒置狀態也不會受存keepAliveTime限制。除非將allowCoreThreadTimeOut設置爲true

  • maximumPoolSize

    線程池所能容納的最大線程數。超過這個數的線程將被阻塞。當任務隊列爲沒有設置大小的LinkedBlockingDeque時,這個值無效。

  • keepAliveTime

    非核心線程的閒置超時時間,超過這個時間就會被回收。

  • unit

    指定keepAliveTime的單位,如TimeUnit.SECONDS。當將allowCoreThreadTimeOut設置爲true時對corePoolSize生效。

  • workQueue

    線程池中的任務隊列.

    常用的有三種隊列,SynchronousQueue,LinkedBlockingDeque,ArrayBlockingQueue



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章