我做了以下錯誤:有沒有辦法讓ExecutorService遞歸地工作?
- 調用
Executors.newFixedThreadThreadPool
做出池 - 設置
Callable
對象的列表,這樣反過來call
方法試圖啓動對非常相同的線程池任務 - 將它們放到隊列與
invokeAll
的結果對executo的隊列死鎖r服務。
我讀過的Javadoc似乎沒有禁止這組活動。我錯過了什麼?有什麼方法來定製隊列或服務,以便這可以工作?
我做了以下錯誤:有沒有辦法讓ExecutorService遞歸地工作?
Executors.newFixedThreadThreadPool
做出池Callable
對象的列表,這樣反過來call
方法試圖啓動對非常相同的線程池任務invokeAll
的結果對executo的隊列死鎖r服務。
我讀過的Javadoc似乎沒有禁止這組活動。我錯過了什麼?有什麼方法來定製隊列或服務,以便這可以工作?
我對你的問題的理解就像下面的測試案例,它按照記錄(如你所說)工作,並且我很樂意用於生產。你的例子與這個有什麼不同?
import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
class Scratch {
public static void main(String[] args) throws InterruptedException {
final ExecutorService pool = Executors.newFixedThreadPool(1);
pool.submit(new Callable<Void>() {
@Override
public Void call() throws Exception {
pool.submit(new Callable<Void>() {
@Override
public Void call() throws Exception {
System.out.println(new Date() + ": Second callable being run.");
pool.shutdown();
return null;
}
});
System.out.println(new Date() + ": First callable going to sleep...");
Thread.sleep(2000);
System.out.println(new Date() + ": First callable finished!");
return null;
}
});
pool.awaitTermination(2, TimeUnit.MINUTES);
}
}
版畫一樣的東西:
Mon Feb 20 01:18:00 GMT 2012: First callable going to sleep...
Mon Feb 20 01:18:02 GMT 2012: First callable finished!
Mon Feb 20 01:18:02 GMT 2012: Second callable being run.
我的外層功能是使用pool.invokeAll,而不是pool.submit,所以它正在等待。我現在懷疑問題是所有的線程都用在'外部'線程上,所以沒有任何工作可以完成。換句話說,我是一個白癡。 – bmargulies 2012-02-20 01:59:41
儘管如此,一個正在執行的Callable應該仍然能夠'submit()'一個新的Callable(因爲'submit()'永遠不會阻塞'newFixedThreadPool()')?除非你在Callables中也使用'pool.invokeAll()'? – FauxFaux 2012-02-20 02:05:16
這是在lucene裏面,我不知道。但是,如果所有的線程都在外面用完了,那麼內部可以提交,但從來沒有進展,然後外面的任何一個都不會完成。 – bmargulies 2012-02-20 02:30:06
我也有類似的問題。假設我的線程池只有一個線程。我的外部Callable獲取線程並調用一個子任務Callable。然後等待子任務完成。但是,由於池中唯一的線程已經與外部任務相關聯,因此永遠不會將其分配給內部任務,從而導致死鎖。這個評估是否正確,或者我錯過了什麼? – 2013-10-11 15:09:05
考慮到這一點之後,如果分支數量(即產生子任務的任務數量)大於池中線程的數量,似乎可能陷入死鎖。所以,當你的分支計數超過線程數時,你可以連續執行子任務,而不是提交它們以便並行執行。我沒有嘗試過,但從概念上來說,它似乎應該起作用。 – 2013-10-11 18:51:09