執行緒執行者(三)建立一個大小固定的執行緒執行者
宣告:本文是《 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個執行緒的執行者。
以下截圖展示了執行這個示例輸出的一部分:
寫入的程式輸出到控制檯,你已經使用了ThreadPoolExecutor類的一些方法,包括:
- getPoolSize():此方法返回執行緒池實際的執行緒數。
- getActiveCount():此方法返回在執行者中正在執行任務的執行緒數。
你可以看出這些方法的輸出是5,表明執行者有5個執行緒。它本沒有超出既定的最大執行緒數。
當你提交最後的任務給執行者,它只有5個活動的執行緒。剩下的95個任務將等待空閒執行緒。我們使用getTaskCount()方法來顯示有多少個任務已經提交給執行者。
不止這些…
Executors類同時提供newSingleThreadExecutor()方法。這是大小固定的執行緒執行者的一個極端例子。它建立只有一個執行緒的執行者,所以它在任意時刻只能執行一個任務。
參見
- 在第4章,執行緒執行者中的建立執行緒執行者指南
- 在第8章,測試併發應用程式中的監控Executor framework指南