The difference between the Runnable and Callable interfaces in Java
在设计Java中的并发线程时,使用EDCOX1 0和EDCOX1 1接口的区别是什么?为什么要选择另一个?
请参阅此处的说明。
The Callable interface is similar to
Runnable, in that both are designed
for classes whose instances are
potentially executed by another
thread. A Runnable, however, does not
return a result and cannot throw a
checked exception.
What are the differences in the applications of
Runnable andCallable . Is the difference only with the return parameter present inCallable ?
基本上,是的。看看这个问题的答案。还有雅瓦多,以东王的子孙(7)。
What is the need of having both if
Callable can do all thatRunnable does?
因为
自从Java 1以来,EDCOX1的2位一直存在,但是EDCOX1 7的引用仅在Java 1.5中引入。处理
而且,很明显,在一些用例中,任务不需要返回结果或抛出检查过的异常。对于这些用例,使用
Callable 需要实现call() 方法,Runnable 需要实现run() 方法。Callable 可以返回值,但Runnable 不能返回值。Callable 可以抛出已检查的异常,但Runnable 不能。Callable 可用于ExecutorService#invokeXXX(Collection extends Callable 方法,但> tasks) Runnable 不能。
我在另一个博客中发现了这一点,它可以解释更多这些差异:
虽然这两个接口都是由希望在不同执行线程中执行的类实现的,但是这两个接口之间的差别不大,即:
Callable 实例返回V 类型的结果,而Runnable 实例不返回。Callable 实例可以抛出检查的异常,而Runnable 实例不能
Java的设计者感觉需要扩展EDCOX1 2接口的能力,但是它们不想影响EDCOX1×2接口的使用,这可能是他们为什么要在Java 1.5中拥有一个单独的接口名为EDCOX1×7的接口,而不是改变已经存在的EDCOX1×2。
让我们看看在哪里可以使用runnable和callable。
可运行和可调用都在不同于调用线程的线程上运行。但是callable可以返回值,runnable不能。那么,这到底在哪里适用呢?
runnable:如果您有一个fire-and-forget任务,那么使用runnable。将代码放在可运行文件中,当调用run()方法时,可以执行任务。当您执行任务时,调用线程实际上并不关心。
可调用:如果您试图从任务中检索值,请使用可调用。现在,可自行调用将无法完成该任务。您将需要一个围绕可调用对象的未来,并获得未来的价值观。获取()。在这里,调用线程将被阻塞,直到将来返回结果,而结果又等待Callable的call()方法执行。
因此,考虑一个到目标类的接口,其中定义了可运行和可调用的包装方法。调用类将随机调用您的接口方法,不知道哪些方法是可运行的,哪些方法是可调用的。在调用可调用方法之前,可运行方法将异步执行。在这里,调用类的线程将被阻塞,因为您正在从目标类中检索值。
注意:在目标类中,您可以在单个线程执行器上调用callable和runnable,使这个机制类似于串行调度队列。因此,只要调用方调用可运行的包装方法,调用线程就可以快速执行而不阻塞。一旦调用一个包装在未来方法中的可调用项,它就必须阻塞,直到执行所有其他排队项为止。只有这样,方法才会返回值。这是一种同步机制。
Oracle文档中这些接口的用途:
可运行接口应该由任何类实现,这些类的实例将由
可调用:返回结果并可能引发异常的任务。实现者定义了一个没有被调用的参数的方法。
其他差异:
可以通过
例子:
用
与
细微差别:对于
1 2 3 4 5 6 7 8 9 | public interface Callable<V> { /** * Computes a result, or throws an exception if unable to do so. * * @return computed result * @throws Exception if unable to compute a result */ V call() throws Exception; } |
另一方面,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public interface Runnable { /** * When an object implementing interface <wyn>Runnable</wyn> is used * to create a thread, starting the thread causes the object's * <wyn>run</wyn> method to be called in that separately executing * thread. * <p> * The general contract of the method <wyn>run</wyn> is that it may * take any action whatsoever. * * @see java.lang.Thread#run() */ public abstract void run(); } |
总的来说,很少有显著的区别是
一些相似之处包括
ExecutorService接口中的方法是
1 2 3 |
正如前面提到的,Callable是一个相对较新的接口,它是作为并发包的一部分引入的。可调用和可运行都可以与执行器一起使用。类线程(实现可运行的本身)只支持可运行的。
您仍然可以对执行器使用runnable。Callable的优点是,您可以将其发送给执行器,并立即返回在执行完成后将更新的未来结果。同样的方法也可以用runnable实现,但在这种情况下,您必须自己管理结果。例如,您可以创建保存所有结果的结果队列。其他线程可以在此队列上等待并处理到达的结果。
1 2 3 4 5 6 7 8 9 | +-------------------------------------+--------------------------------------------------------------------------------------------------+ | Runnable | Callable<T> | +-------------------------------------+--------------------------------------------------------------------------------------------------+ | Introduced in Java 1.0 of java.lang | Introduced in Java 1.5 of java.util.concurrent library | | Runnable cannot be parametrized | Callable is a parametrized type whose type parameter indicates the return type of its run method | | Runnable has run() method | Callable has call() method | | Runnable.run() returns void | Callable.call() returns a value of Type T | | Can not throw Checked Exceptions | Can throw Checked Exceptions | +-------------------------------------+--------------------------------------------------------------------------------------------------+ |
Java的设计者感觉需要扩展EDCOX1 3接口的能力,但是它们不想影响EDCOX1 3接口的使用,这可能是他们为什么要在Java 1.5中拥有一个单独的接口名为EDCOX1×2的接口,而不是改变已经存在的EDCOX1和3的接口。自从Java 1以来,是Java的一部分。来源
可调用和可运行的区别如下:
可调用和可运行两者都很相似,可以用于实现线程。在实现runnable的情况下,必须实现run()方法,但在可调用的情况下,必须实现call()方法,这两种方法的工作方式相似,但call()方法有更大的灵活性,两者之间有一些区别。
可运行和可调用的区别如下--
1)runnable的run()方法返回void,意味着如果您希望线程返回一些可以进一步使用的东西,那么对于runnable run()方法您没有选择。有一个"可调用"的解决方案,如果您想以对象的形式返回任何东西,那么您应该使用可调用而不是可运行。可调用接口具有返回对象的方法"call()"。
方法签名-可运行的>
1 | public void run(){} |
可调用的>
1 |
2)对于runnable run()方法,如果出现任何选中的异常,则必须使用try catch块进行处理,但是对于callable call()方法,可以按如下方式引发选中的异常
3)RunnFabess来自遗留Java 1版本,但可调用的Java 1.5版本采用ExcUnter框架。
如果您熟悉执行器,那么应该使用Callable而不是Runnable。
希望你能理解。