91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在java項目中自定義線程池

發布時間:2020-12-03 15:49:01 來源:億速云 閱讀:292 作者:Leah 欄目:編程語言

怎么在java項目中自定義線程池?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

使用線程池時,可以使用 newCachedThreadPool()或者 newFixedThreadPool(int)等方法,其實我們深入到這些方法里面,就可以看到它們的是實現方式是這樣的。

 public static ExecutorService newCachedThreadPool() {
     return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                    60L, TimeUnit.SECONDS,
                    new SynchronousQueue<Runnable>());
}
public static ExecutorService newFixedThreadPool(int nThreads) {
     return new ThreadPoolExecutor(nThreads, nThreads,
                    0L, TimeUnit.MILLISECONDS,
                    new LinkedBlockingQueue<Runnable>());
 }

包括其他幾種不同類型的線程池,其實都是通過 ThreadPoolExecutor這個核心類來創建的,如果我們要自定義線程池,那么也是通過這個類來實現的。

怎么在java項目中自定義線程池

該類有四個構造方法,查看源碼可以看到,頭三個構造方法,其實都是調用的第四個構造方法,所以我們就解釋一下第四個構造方法的參數含義。

 public ThreadPoolExecutor(int corePoolSize,
               int maximumPoolSize,
               long keepAliveTime,
               TimeUnit unit,
               BlockingQueue<Runnable> workQueue,
               ThreadFactory threadFactory,
               RejectedExecutionHandler handler)

corePoolSize:核心線程池的大小,在線程池被創建之后,其實里面是沒有線程的。(當然,調用prestartAllCoreThreads()或者prestartCoreThread()方法會預創建線程,而不用等著任務的到來)。當有任務進來的時候,才會創建線程。當線程池中的線程數量達到corePoolSize之后,就把任務放到 緩存隊列當中。(就是 workQueue)。

maximumPoolSize:最大線程數量是多少。它標志著這個線程池的最大線程數量。如果沒有最大數量,當創建的線程數量達到了 某個極限值,到最后內存肯定就爆掉了。

keepAliveTime:當線程沒有任務時,最多保持的時間,超過這個時間就被終止了。默認情況下,只有 線程池中線程數量 大于 corePoolSize時,keepAliveTime值才會起作用。也就說說,只有在線程池線程數量超出corePoolSize了。我們才會把超時的空閑線程給停止掉。否則就保持線程池中有 corePoolSize 個線程就可以了。

Unit:參數keepAliveTime的時間單位,就是 TimeUnit類當中的幾個屬性。

如下圖:

怎么在java項目中自定義線程池

workQueue:用來存儲待執行任務的隊列,不同的線程池它的隊列實現方式不同(因為這關系到排隊策略的問題)比如有以下幾種

ArrayBlockingQueue:基于數組的隊列,創建時需要指定大小。

LinkedBlockingQueue:基于鏈表的隊列,如果沒有指定大小,則默認值是 Integer.MAX_VALUE。(newFixedThreadPool和newSingleThreadExecutor使用的就是這種隊列)。

SynchronousQueue:這種隊列比較特殊,因為不排隊就直接創建新線程把任務提交了。(newCachedThreadPool使用的就是這種隊列)。

threadFactory:線程工廠,用來創建線程。

Handler:拒絕執行任務時的策略,一般來講有以下四種策略,

(1) ThreadPoolExecutor.AbortPolicy 丟棄任務,并拋出 RejectedExecutionException 異常。

(2) ThreadPoolExecutor.CallerRunsPolicy:該任務被線程池拒絕,由調用 execute方法的線程執行該任務。

(3) ThreadPoolExecutor.DiscardOldestPolicy : 拋棄隊列最前面的任務,然后重新嘗試執行任務。

(4) ThreadPoolExecutor.DiscardPolicy,丟棄任務,不過也不拋出異常。

看一個demo ,示例代碼地址:src/thread_runnable/CustomThreadPool.java

class CustomTask implements Runnable{
  private int id;
  public CustomTask(int id) {
    this.id = id;
  }

  @Override
  public void run() {
    // TODO Auto-generated method stub
    System.out.println("#" + id + "  threadId=" + Thread.currentThread().getName() );
    try {
      TimeUnit.MILLISECONDS.sleep(100);
    }catch(InterruptedException e){
      e.printStackTrace();
    }
  }
  
}

public class CustomThreadPool {
  public static void main(String[] args) {
    // TODO Auto-generated method stub
      BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>(10);
      ThreadPoolExecutor pool = new ThreadPoolExecutor(3, 5, 60, TimeUnit.MICROSECONDS, queue);
      
      for (int i=0; i<7; i++){
        Runnable task = new CustomTask(i);
        pool.execute(task);
      }
      
      pool.shutdown();
  }

}

輸出結果: 

 怎么在java項目中自定義線程池

從這個例子,可以看出,雖然我們有7個任務,但是實際上,只有三個線程在運行。

那么當我們提交任務給線程池之后,它的處理策略是什么呢?

怎么在java項目中自定義線程池 

(1),如果當前線程池線程數目小于 corePoolSize(核心池還沒滿呢),那么就創建一個新線程去處理任務。

(2),如果核心池已經滿了,來了一個新的任務后,會嘗試將其添加到任務隊列中,如果成功,則等待空閑線程將其從隊列中取出并且執行,如果隊列已經滿了,則繼續下一步。

(3),此時,如果線程池線程數量 小于 maximumPoolSize,則創建一個新線程執行任務,否則,那就說明線程池到了最大飽和能力了,沒辦法再處理了,此時就按照拒絕策略來處理。(就是構造函數當中的Handler對象)。

(4),如果線程池的線程數量大于corePoolSize,則當某個線程的空閑時間超過了keepAliveTime,那么這個線程就要被銷毀了,直到線程池中線程數量不大于corePoolSize為止。

舉個通俗易懂的例子,公司要設立一個項目組來處理某些任務,hr部門給的人員編制是10個人(corePoolSize)。同時給他們專門設置了一間有15個座位(maximumPoolSize)的辦公室。最開始的時候來了一個任務,就招聘一個人。就這樣,一個一個的招聘,招滿了十個人,不斷有新的任務安排給這個項目組,每個人也在不停的接任務干活。不過后來任務越來越多,十個人無法處理完了。其他的任務就只能在走廊外面排隊了。后來任務越來越多,走廊的排隊隊伍也擠不下。然后只好找找一些臨時工來幫助完成任務。因為辦公室只有15個座位,所以它們最多也就只能找5個臨時工。可是任務依舊越來越多,根本處理不完,那沒辦法,這個項目組只好拒絕再接新任務。(拒絕的方式就是 Handler),最后任務漸漸的少了,大家都比較清閑了。所以就決定看大家表現,誰表現不好,誰就被清理出這個辦公室(空閑時間超過 keepAliveTime),直到 辦公室只剩下10個人(corePoolSize),維持固定的人員編制為止。

關于線程池,ThreadPoolExecutor還提供了一些需要注意的方法:

(1) shutdown(),平滑的關閉線程池。(如果還有未執行完的任務,就等待它們執行完)。

(2) shutdownNow()。簡單粗暴的關閉線程池。(沒有執行完的任務也直接關閉)。

(3) setCorePoolSize()。設置/更改核心池的大小。

(4) setMaximumPoolSize(),設置/更改線程池中最大線程的數量限制。

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

抚顺县| 盐边县| 汶川县| 扶绥县| 江安县| 双牌县| 金溪县| 新建县| 瓦房店市| 收藏| 遂溪县| 英吉沙县| 子长县| 通州市| 民权县| 达州市| 离岛区| 民丰县| 灵武市| 崇礼县| 汽车| 彰武县| 江孜县| 维西| 永平县| 六枝特区| 聂拉木县| 万州区| 荆州市| 勃利县| 盐池县| 阳东县| 茌平县| 临潭县| 灵宝市| 临夏县| 新乡县| 越西县| 鄂伦春自治旗| 区。| 科技|