我做了以下错误:有没有办法让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