Java 为什么可以';使用BlockingQueue实例化ThreadPoolExecutor<;可调用>;;为什么只阻塞队列<;可运行>;?
我的理解是在1.5中添加了callable,而runnable接口保持原样,以防止世界末日。为什么我不能实例化一个Java 为什么可以';使用BlockingQueue实例化ThreadPoolExecutor<;可调用>;;为什么只阻塞队列<;可运行>;?,java,jdk1.5,threadpoolexecutor,Java,Jdk1.5,Threadpoolexecutor,我的理解是在1.5中添加了callable,而runnable接口保持原样,以防止世界末日。为什么我不能实例化一个(core、max、tu、unit、new BlockingQueue())-为什么队列必须只使用runnable?在内部,如果我提交,invokeAll,invokeAny callables,这应该没问题吧?另外,如果返回一个可调用的列表?作为更一般的回答,您不能通过更改类型参数来影响Java程序的运行时行为。如果分支可以基于类型参数重新路由,则无。如果您希望从API获得不同的行
(core、max、tu、unit、new BlockingQueue())
-为什么队列必须只使用runnable?在内部,如果我提交,invokeAll,invokeAny callables,这应该没问题吧?另外,如果返回一个可调用的列表?作为更一般的回答,您不能通过更改类型参数来影响Java程序的运行时行为。如果分支可以基于类型参数重新路由,则无。如果您希望从API获得不同的行为,请不要在类型参数的选择中寻找解决方案
在这种特殊情况下,Runnable
是一种更通用的对象类型:它是执行器内部可以提交给线程的工作单元。例如,Runnable
可以包含调用Callable
并将其结果保存在某处的代码。由于类型擦除,它不能同时使用BlockingQueue
和BlockingQueue
;这两个重载将具有相同的原始类型BlockingQueue
,因此会发生冲突
不过,我不知道你会如何处理提交给执行人的可调用的列表。你会如何处理他们的结果?它会去哪里
听起来你想要一份工作。您可以使用提交一个可调用的集合,您将获得一个未来的集合,一旦它们可用,您就可以从中获取值。您可以提交可调用的,但它们在内部包装为可运行的(实际上是未来任务,它实现了可运行的). shutDownNow()
只会返回Runnables
,就像tin上所说的那样
如果您想获取尚未运行的可调用项列表
,您需要自己跟踪它们(例如,保存它们的列表,并让它们在被调用时负责将自己从列表中删除)。因为您无法将可运行的
添加到可调用的
队列中,我想跟踪哪些callables没有执行。假设我提交/invokeAll/invokean任何一个可调用的列表,在我可以遍历它们的所有future.get之前,或者甚至在我可以开始迭代之前,应用程序已经关闭,并且我们发出了一个shutDownNow,我能期待一个甚至并没有开始运行的列表吗?我想答案是否定的,正如@david所描述的那样-moles@SaadShakil您可以遍历从invokeAll
获得的列表
,并检查每个列表中是否有isTerminate()
。如果不了解更详细的用例,很难给出更具体的建议。感谢您的指导。为了更好地理解,您建议我使用包装callable的runnable(这将在原始runnable的提交者之外的其他地方吐出结果?我如何获取它[根据环境,必须有很多方法]通常情况下?这种读取结果的能力将决定什么是有效的,什么是无效的,我认为这更重要,不过,我仍然关心此时执行的开始)。我想我已经意识到您的困惑:您认为传入队列是Executor公共API的一部分,您可以在执行器运行时检查内容,等等。但事实上,您正在传递执行器内部的构建块,构造函数接受它的原因是因为队列实现的细节影响执行器行为的重要整体方面。在正常执行器操作期间,您不应该以任何方式接触该队列。