[英]Java - Reusing Thread Pool
對於我的Java項目,我想並行執行兩個任務並將其結果合並。 問題是我必須在一種方法中執行此操作,該方法每次執行都會被調用多次(可能是1000次或更多)。 我嘗試使用ExecutorService及其線程池,但是如果我將ExecutorService聲明為類字段並開始向其提交工作,則有時會拋出
java.lang.OutOfMemoryError: unable to create new native thread
因此,我決定使用以下代碼:
ExecutorService executor = Executors.newFixedThreadPool(2);
Future<Integer> taskOne = executor.submit(new Callable<Integer> () {
public Integer call() throws Exception {
//Do work...
return 0;
}
});
Future<Integer> task2 = executor.submit(new Callable<Integer> () {
public Integer call() throws Exception {
//Do work...
return 0;
}
});
task1.get();
task2.get();
executor.shutdown();
while(!executor.isTerminated());
問題在於,使用這種新方法,與單線程解決方案相比,應用程序性能甚至更差。 我認為這是由於在每個方法調用上創建新線程池的開銷。
因此,我的問題是:是否有一種方法可以執行相同的任務,而不必創建和關閉每個方法調用的線程池?
謝謝。
我並不一定要說它的劣質設計,而是要考慮的幾件事。 就個人而言,我喜歡線程池,並且如果使用正確,它是一個可靠的解決方案。
性能下降的原因是,固定池大小為2時,一次只能運行兩個線程。 可能您需要更大的數字-可能是10,可能是100-但至少您可以對其進行構圖,以免耗盡內存。
就是說,如果由於創建了太多線程而導致原始設計用完了內存,那么您肯定需要限制一次活動線程的數量,因此您的性能將受到一定的打擊……它只是不需要要么全部要么一無所有。
您還可以使用無限執行程序線程池,假設正在運行的線程會及時返回,以使您仍然不會使線程最大化。 如果線程以某種確定性的方式返回,則當線程返回到池中時,它可以立即用於下一個可用任務,而無需創建任何東西。 所以這很好。
綜上所述,查看異常消息,也有可能在操作系統級別上無法創建更多線程,無論您在Java中所做的工作如何。 我有一個在CentOS上運行的服務,並且我合理地不得不增加每個進程的允許線程數(在這種情況下,一個Java進程在運行我的服務),因為有一個最大值,而且我正在嘗試。 如果您正在運行某種linux風格,也可能是這樣,尤其是因為看起來線程本身除了返回外什么都不做。
您描述的類字段解決方案聽起來像是一個更好的設計。 該游泳池的大小是多少? 您應該調試OutOfMemoryError
而不是切換到劣等設計。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.