簡體   English   中英

Java-重用線程池

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM