为什么我不能用BlockingQueue <callable>实例化ThreadPoolExecutor;为什么只有BlockingQueue <runnable>?</runnable> </callable>

时间:2013-08-09 18:41:08

标签: java jdk1.5 threadpoolexecutor

我的理解是在1.5中添加了callable,并且runnable接口保持原样以防止世界结束。为什么我不能实例化ThreadPoolExecutor (core, max, tu, unit, new BlockingQueue<Callable>()) - 为什么队列必须只运行runnable?在内部,如果我要提交,invokeAll,invokeAny callables,这应该没问题吧?另外,shutDownNow()会返回一个callables列表吗?

3 个答案:

答案 0 :(得分:8)

您可以提交Callables,但它们会在内部包装为Runnables(实际为FutureTasks,实现Runnable)。 shutDownNow()只会返回Runnables,就像它在锡上所说的那样。

如果你想获得尚未运行的Callables列表,你需要以某种方式自己跟踪它们(例如,保留它们的列表并让它们负责将它们从他们被召唤时的清单。)

答案 1 :(得分:2)

作为更一般的答案,您不能通过更改类型参数来影响Java程序的运行时行为。可以根据类型参数重新路由if分支。如果您发现自己处于希望从API获得不同行为的情况,请不要在选择类型参数时寻找解决方案。

在这种特殊情况下,Runnable是一种更通用的对象类型:它是Executor的内部可以提交给线程的工作单元。例如,Runnable可以包含调用Callable并将结果保存在某处的代码。

答案 2 :(得分:1)

由于类型擦除,BlockingQueue<Callable<T>>BlockingQueue<Runnable>不能同时使用;两个重载都具有相同的原始类型BlockingQueue,因此会发生冲突。

我不知道你会对提交者提交的Callable列表做些什么。你会对他们的结果做些什么?它会去哪里?

听起来你想要Future<T>。您可以使用invokeAll提交Callable<T>的集合,然后您将收到Future<T>个集合,您可以在它们可用后获取值。