1. 程式人生 > >執行緒執行者(三)建立一個大小固定的執行緒執行者

執行緒執行者(三)建立一個大小固定的執行緒執行者

宣告:本文是《 Java 7 Concurrency Cookbook 》的第四章,作者: Javier Fernández González     譯者:許巧輝     校對:方騰飛,葉磊

建立一個大小固定的執行緒執行者

當你使用由Executors類的 newCachedThreadPool()方法建立的基本ThreadPoolExecutor,你會有執行者執行在某一時刻的執行緒數的問題。這個執行者為每個接收到的任務建立一個執行緒(如果池中沒有空閒的執行緒),所以,如果你提交大量的任務,並且它們有很長的(執行)時間,你會使系統過載和引發應用程式效能不佳的問題。

如果你想要避免這個問題,Executors類提供一個方法來建立大小固定的執行緒執行者。這個執行者有最大執行緒數。 如果你提交超過這個最大執行緒數的任務,這個執行者將不會建立額外的執行緒,並且剩下的任務將會阻塞,直到執行者有空閒執行緒。這種行為,保證執行者不會引發應用程式效能不佳的問題。

在這個指南中,你將繼續學習怎樣建立一個大小固定的執行緒執行者,然後修改本章第一個示例的實現。

準備工作…

你應該事先閱讀本章的建立執行緒執行者指南,並且實現所有演示的示例,因為接下來你需要繼續修改這些示例。

這個指南的例子使用Eclipse IDE實現。如果你使用Eclipse或其他IDE,如NetBeans,開啟它並建立一個新的Java專案。

如何做…

按以下步驟來實現的這個例子:

1.實現本章第一個指南描述的示例,開啟Server類,修改它的構造器。使用newFixedThreadPool()方法建立執行者並傳入5作為引數。

public Server(){
executor=(ThreadPoolExecutor)Executors.newFixedThreadPool(5);
}

2.修改executeTask()方法,包含額外的日誌資訊行。呼叫getTaskCount()方法,獲取已經提交給執行者的任務數。

System.out.printf("Server: Task Count: %d\n",executor.
getTaskCount());

它是如何工作的…

在本例中,你已經使用Executors類的newFixedThreadPool()方法來建立執行者。這個方法建立一個有最大執行緒數的執行者。如果你提交超過最大執行緒數的任務,剩下的任務將會被阻塞,直到有空閒的執行緒來處理它們。這個方法接收一個你想要讓執行者擁有最大執行緒數的引數。在你的例子中,你已經建立了擁有5個執行緒的執行者。

以下截圖展示了執行這個示例輸出的一部分:

2

寫入的程式輸出到控制檯,你已經使用了ThreadPoolExecutor類的一些方法,包括:

  • getPoolSize():此方法返回執行緒池實際的執行緒數。
  • getActiveCount():此方法返回在執行者中正在執行任務的執行緒數。

你可以看出這些方法的輸出是5,表明執行者有5個執行緒。它本沒有超出既定的最大執行緒數。

當你提交最後的任務給執行者,它只有5個活動的執行緒。剩下的95個任務將等待空閒執行緒。我們使用getTaskCount()方法來顯示有多少個任務已經提交給執行者。

不止這些…

Executors類同時提供newSingleThreadExecutor()方法。這是大小固定的執行緒執行者的一個極端例子。它建立只有一個執行緒的執行者,所以它在任意時刻只能執行一個任務。

參見

  • 在第4章,執行緒執行者中的建立執行緒執行者指南
  • 在第8章,測試併發應用程式中的監控Executor framework指南