Java中Runnable和Callable接口的区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/141284/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 08:49:11  来源:igfitidea点击:

The difference between the Runnable and Callable interfaces in Java

javamultithreadinginterfacerunnablecallable

提问by Scottm

What is the difference between using the Runnableand Callableinterfaces when designing a concurrent thread in Java, why would you choose one over the other?

在 Java 中设计并发线程时使用RunnableCallable接口有什么区别,为什么要选择一个?

采纳答案by Jorge Ferreira

See explanation here.

请参阅此处的说明。

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.

Callable 接口与 Runnable 类似,因为两者都是为那些实例可能由另一个线程执行的类而设计的。但是,Runnable 不返回结果,也不能抛出已检查的异常。

回答by amoran

I found this in another blog that can explain it a little bit more these differences:

我在另一篇博客中发现了这一点,可以更详细地解释这些差异

Though both the interfaces are implemented by the classes who wish to execute in a different thread of execution, but there are few differences between the two interface which are:

虽然这两个接口都是由希望在不同执行线程中执行的类实现的,但是这两个接口之间几乎没有区别,它们是:

  • A Callable<V>instance returns a result of type V, whereas a Runnableinstance doesn't.
  • A Callable<V>instance may throw checked exceptions, whereas a Runnableinstance can't
  • 一个Callable<V>实例返回类型的结果V,而一个Runnable实例不会。
  • 一个Callable<V>实例可能会抛出已检查的异常,而一个Runnable实例不能

The designers of Java felt a need of extending the capabilities of the Runnableinterface, but they didn't want to affect the uses of the Runnableinterface and probably that was the reason why they went for having a separate interface named Callablein Java 1.5 than changing the already existing Runnable.

Java 的设计者觉得需要扩展Runnable接口的功能,但他们不想影响Runnable接口的使用,这可能就是为什么他们选择Callable在 Java 1.5 中命名一个单独的接口而不是改变已经存在的接口的原因。现有的Runnable

回答by Stephen C

What are the differences in the applications of Runnableand Callable. Is the difference only with the return parameter present in Callable?

Runnable和的应用有什么区别Callable。区别仅与 中存在的返回参数有关Callable吗?

Basically, yes. See the answers to this question. And the javadoc for Callable.

基本上,是的。请参阅此问题的答案。以及用于Callable.

What is the need of having both if Callablecan do all that Runnabledoes?

如果Callable可以做所有的事情,有什么必要同时拥有两者Runnable

Because the Runnableinterface cannotdo everything that Callabledoes!

因为Runnable界面不能做所有能做的事Callable

Runnablehas been around since Java 1.0, but Callablewas only introduced in Java 1.5 ... to handle use-cases that Runnabledoes not support. In theory, the Java team could have changed the signature of the Runnable.run()method, but this would have broken binary compatiblity with pre-1.5 code, requiring recoding when migrating old Java code to newer JVMs. That is a BIG NO-NO. Java strives to be backwards compatible ... and that's been one of Java's biggest selling points for business computing.

Runnable自 Java 1.0 以来一直存在,但Callable仅在 Java 1.5 中引入......以处理Runnable不支持的用例。理论上,Java 团队本可以更改该Runnable.run()方法的签名,但这会破坏与 1.5 之前代码的二进制兼容性,在将旧 Java 代码迁移到新 JVM 时需要重新编码。这是一个很大的禁忌。Java 努力向后兼容……这是 Java 商业计算的最大卖点之一。

And, obviously, there are use-cases where a task doesn't needto return a result or throw a checked exception. For those use-cases, using Runnableis more concise than using Callable<Void>and returning a dummy (null) value from the call()method.

而且,显然,在某些用例中,任务不需要返回结果或抛出已检查的异常。对于这些用例, usingRunnable比使用Callable<Void>nullcall()方法返回一个虚拟 ( ) 值更简洁。

回答by AlexR

As it was already mentioned here Callable is relatively new interface and it was introduced as a part of concurrency package. Both Callable and Runnable can be used with executors. Class Thread (that implements Runnable itself) supports Runnable only.

正如这里已经提到的,Callable 是一个相对较新的接口,它是作为并发包的一部分引入的。Callable 和 Runnable 都可以与执行程序一起使用。Thread 类(实现 Runnable 本身)仅支持 Runnable。

You can still use Runnable with executors. The advantage of Callable that you can send it to executor and immediately get back Future result that will be updated when the execution is finished. The same may be implemented with Runnable, but in this case you have to manage the results yourself. For example you can create results queue that will hold all results. Other thread can wait on this queue and deal with results that arrive.

您仍然可以将 Runnable 与执行程序一起使用。Callable 的优点是您可以将其发送到执行程序并立即返回 Future 结果,该结果将在执行完成时更新。Runnable 也可以实现相同的功能,但在这种情况下,您必须自己管理结果。例如,您可以创建将保存所有结果的结果队列。其他线程可以在这个队列上等待并处理到达的结果。

回答by nikli

  • A Callableneeds to implement call()method while a Runnableneeds to implement run()method.
  • A Callablecan return a value but a Runnablecannot.
  • A Callablecan throw checked exception but a Runnablecannot.
  • A Callablecan be used with ExecutorService#invokeXXX(Collection<? extends Callable<T>> tasks)methods but a Runnablecannot be.

    public interface Runnable {
        void run();
    }
    
    public interface Callable<V> {
        V call() throws Exception;
    }
    
  • ACallable需要实现call()方法,而A需要Runnable实现run()方法。
  • ACallable可以返回一个值,但 aRunnable不能。
  • ACallable可以抛出已检查的异常,但Runnable不能。
  • ACallable可以与ExecutorService#invokeXXX(Collection<? extends Callable<T>> tasks)方法一起使用,但 aRunnable不能。

    public interface Runnable {
        void run();
    }
    
    public interface Callable<V> {
        V call() throws Exception;
    }
    

回答by Kris Subramanian

Let us look at where one would use Runnable and Callable.

让我们看看在哪里可以使用 Runnable 和 Callable。

Runnable and Callable both run on a different thread than the calling thread. But Callable can return a value and Runnable cannot. So where does this really apply.

Runnable 和 Callable 都在与调用线程不同的线程上运行。但是 Callable 可以返回一个值而 Runnable 不能。那么这在何处真正适用。

Runnable: If you have a fire and forget task then use Runnable. Put your code inside a Runnable and when the run() method is called, you can perform your task. The calling thread really does not care when you perform your task.

Runnable:如果你有一个火而忘记的任务,那么使用 Runnable。将您的代码放在 Runnable 中,当 run() 方法被调用时,您就可以执行您的任务。当您执行任务时,调用线程实际上并不关心。

Callable: If you are trying to retrieve a value from a task, then use Callable. Now callable on its own will not do the job. You will need a Future that you wrap around your Callable and get your values on future.get (). Here the calling thread will be blocked till the Future comes back with results which in turn is waiting for Callable's call() method to execute.

Callable:如果您尝试从任务中检索值,请使用 Callable。现在可调用本身不会完成这项工作。您将需要一个 Future 来包装 Callable 并在 future.get() 上获取您的值。这里调用线程将被阻塞,直到 Future 返回结果,然后等待 Callable 的 call() 方法执行。

So think about an interface to a target class where you have both Runnable and Callable wrapped methods defined. The calling class will randomly call your interface methods not knowing which is Runnable and which is Callable. The Runnable methods will execute asynchronously, till a Callable method is called. Here the calling class's thread will block since you are retrieving values from your target class.

因此,考虑一个目标类的接口,其中定义了 Runnable 和 Callable 包装方法。调用类会随机调用你的接口方法,不知道哪个是 Runnable 哪个是 Callable。Runnable 方法将异步执行,直到调用 Callable 方法。这里调用类的线程将阻塞,因为您正在从目标类中检索值。

NOTE : Inside your target class you can make the calls to Callable and Runnable on a single thread executor, making this mechanism similar to a serial dispatch queue. So as long as the caller calls your Runnable wrapped methods the calling thread will execute really fast without blocking. As soon as it calls a Callable wrapped in Future method it will have to block till all the other queued items are executed. Only then the method will return with values. This is a synchronization mechanism.

注意:在您的目标类中,您可以在单个线程执行器上调用 Callable 和 Runnable,使这种机制类似于串行调度队列。因此,只要调用者调用您的 Runnable 包装方法,调用线程就会执行得非常快而不会阻塞。一旦它调用一个包含在 Future 方法中的 Callable,它就必须阻塞,直到所有其他排队的项目都被执行。只有这样,该方法才会返回值。这是一种同步机制。

回答by Aniket Thakur

Callableinterface declares call()method and you need to provide generics as type of Object call() should return -

Callable接口声明call()方法,您需要提供泛型作为对象调用()的类型应该返回 -

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;
}

Runnableon the other hand is interface that declares run()method that is called when you create a Thread with the runnable and call start() on it. You can also directly call run() but that just executes the run() method is same thread.

Runnable另一方面是声明run()方法的接口,当您使用可运行对象创建线程并在其上调用 start() 时调用该方法。您也可以直接调用 run() 但只是执行 run() 方法是同一个线程。

public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used 
     * to create a thread, starting the thread causes the object's 
     * <code>run</code> method to be called in that separately executing 
     * thread. 
     * <p>
     * The general contract of the method <code>run</code> is that it may 
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}

To summarize few notable Difference are

总结几个显着的区别是

  1. A Runnableobject does not return a result whereas a Callableobject returns a result.
  2. A Runnableobject cannot throw a checked exception wheras a Callableobject can throw an exception.
  3. The Runnableinterface has been around since Java 1.0 whereas Callablewas only introduced in Java 1.5.
  1. 一个Runnable而对象不返回结果Callable对象返回结果。
  2. 一个Runnable对象不能抛出checked异常wheras一个Callable对象可以抛出异常。
  3. Runnable接口自 Java 1.0 以来就存在,而Callable仅在 Java 1.5 中引入。

Few similarities include

很少有相似之处包括

  1. Instances of the classes that implement Runnable or Callable interfaces are potentially executed by another thread.
  2. Instance of both Callable and Runnable interfaces can be executed by ExecutorService via submit() method.
  3. Both are functional interfaces and can be used in Lambda expressions since Java8.
  1. 实现 Runnable 或 Callable 接口的类的实例可能由另一个线程执行。
  2. ExecutorService 可以通过 submit() 方法执行 Callable 和 Runnable 接口的实例。
  3. 两者都是函数式接口,从 Java8 开始就可以在 Lambda 表达式中使用。

Methods in ExecutorService interface are

ExecutorService 接口中的方法是

<T> Future<T> submit(Callable<T> task);
Future<?> submit(Runnable task);
<T> Future<T> submit(Runnable task, T result);

回答by Ravindra babu

Purpose of these interfaces from oracle documentation :

oracle 文档中这些接口的用途:

Runnableinterface should be implemented by any class whose instances are intended to be executed by a Thread. The class must define a method of no arguments called run.

Runnable接口应该由其实例旨在由Thread. 该类必须定义一个名为 的无参数方法run

Callable: A task that returns a result and may throw an exception. Implementors define a single method with no arguments called call. The Callableinterface 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.

Callable:返回结果并可能引发异常的任务。实现者定义了一个没有参数的单一方法,称为调用。该Callable接口类似于Runnable,因为两者都是为实例可能由另一个线程执行的类而设计的。Runnable但是,A不返回结果并且不能抛出已检查的异常。

Other differences:

其他区别:

  1. You can pass Runnableto create a Thread. But you can't create new Thread by passing Callableas parameter. You can pass Callable only to ExecutorServiceinstances.

    Example:

    public class HelloRunnable implements Runnable {
    
        public void run() {
            System.out.println("Hello from a thread!");
        }   
    
        public static void main(String args[]) {
            (new Thread(new HelloRunnable())).start();
        }
    
    }
    
  2. Use Runnablefor fire and forget calls. Use Callableto verify the result.

  3. Callablecan be passed to invokeAllmethod unlike Runnable. Methods invokeAnyand invokeAllperform the most commonly useful forms of bulk execution, executing a collection of tasks and then waiting for at least one, or all, to complete

  4. Trivial difference : method name to be implemented => run()for Runnableand call()for Callable.

  1. 你可以通过Runnable创建一个Thread。但是您不能通过Callable作为参数传递来创建新线程。您只能将 Callable 传递给ExecutorService实例。

    例子:

    public class HelloRunnable implements Runnable {
    
        public void run() {
            System.out.println("Hello from a thread!");
        }   
    
        public static void main(String args[]) {
            (new Thread(new HelloRunnable())).start();
        }
    
    }
    
  2. 使用Runnable消防和忘记调用。使用Callable来验证结果。

  3. Callable与 不同,可以传递给invokeAll方法Runnable。方法invokeAnyinvokeAll执行最常用的批量执行形式,执行一组任务,然后等待至少一个或全部完成

  4. 微不足道的区别:要实现的方法名称 => run()forRunnablecall()for Callable

回答by Raman Gupta

Difference between Callable and Runnable are following:

Callable 和 Runnable 之间的区别如下:

  1. Callable is introduced in JDK 5.0 but Runnable is introduced in JDK 1.0
  2. Callable has call() method but Runnable has run() method.
  3. Callable has call method which returns value but Runnable has run method which doesn't return any value.
  4. call method can throw checked exception but run method can't throw checked exception.
  5. Callable use submit() method to put in task queue but Runnable use execute() method to put in the task queue.
  1. Callable 是在 JDK 5.0 中引入的,而 Runnable 是在 JDK 1.0 中引入的
  2. Callable 有 call() 方法,但 Runnable 有 run() 方法。
  3. Callable 具有返回值的调用方法,但 Runnable 具有不返回任何值的 run 方法。
  4. call 方法可以抛出受检异常,而 run 方法不能抛出受检异常。
  5. Callable 使用 submit() 方法放入任务队列,而 Runnable 使用 execute() 方法放入任务队列。

回答by Premraj

+-------------------------------------+--------------------------------------------------------------------------------------------------+
|              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                                                                     |
+-------------------------------------+--------------------------------------------------------------------------------------------------+

The designers of Java felt a need of extending the capabilities of the Runnableinterface, but they didn't want to affect the uses of the Runnableinterface and probably that was the reason why they went for having a separate interface named Callablein Java 1.5 than changing the already existing Runnableinterface which has been a part of Java since Java 1.0. source

Java 的设计者觉得需要扩展Runnable接口的功能,但他们不想影响Runnable接口的使用,这可能就是为什么他们选择Callable在 Java 1.5 中命名一个单独的接口而不是改变已经存在的接口的原因。现有Runnable接口自 Java 1.0 以来一直是 Java 的一部分。来源