当前位置:  开发笔记 > 编程语言 > 正文

Java中Runnable和Callable接口之间的区别

如何解决《Java中Runnable和Callable接口之间的区别》经验,为你挑选了10个好方法。

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



1> Jorge Ferrei..:

请看这里的解释.

Callable接口类似于Runnable,因为它们都是为其实例可能由另一个线程执行的类而设计的.但是,Runnable不会返回结果,也不会抛出已检查的异常.



2> Stephen C..:

Runnable和和的应用有什么不同Callable.区别仅在于返回参数Callable

基本上,是的.查看此问题的答案.和javadocCallable.

如果Callable可以做到这两点的话,有什么需要Runnable

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

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

而且,显然,有一些用例,其中任务不需要返回结果或抛出已检查的异常.对于那些用例,使用Runnable比使用Callable和返回方法中的dummy(null)值更简洁call().


我想知道你从哪里得到这段历史.这非常有用.
@prash - 基本事实可以在旧教科书中找到.就像果壳中的第一版Java一样.
(@prash - 也是......在Java 1.1时代开始使用Java.)

3> nikli..:

一个Callable需要实现call()方法而Runnable需要实现run()的方法.

A Callable可以返回值但不能返回Runnable.

A Callable可以抛出已检查的异常,但Runnable不能.

A Callable可以与ExecutorService#invokeXXX(Collection> tasks)方法一起使用但Runnable不能使用.

public interface Runnable {
    void run();
}

public interface Callable {
    V call() throws Exception;
}


ExecutorService.submit(Runnable task)也存在并且非常有用
也有Executor.submit(Callable <T>任务),但是您不能调用带有Runnable任务Collection <?的collection的invokeAll或invokeAny?扩展Callable <T >>任务

4> amoran..:

我在另一篇博客中发现了这一点,可以解释一下这些差异:

虽然这两个接口都是由希望在不同的执行线程中执行的类实现的,但两个接口之间的差异很小:

一个Callable实例返回类型的结果V,而一个Runnable实例不会.

一个Callable实例可能抛出检查异常,而Runnable实例不能

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



5> Kris Subrama..:

让我们看一下使用Runnable和Callable的位置.

Runnable和Callable都运行在与调用线程不同的线程上.但是Callable可以返回一个值,而Runnable则不能.那么这真的适用于哪里呢?

Runnable:如果你有一个fire and forget任务,那么使用Runnable.将代码放在Runnable中,当调用run()方法时,您可以执行任务.执行任务时调用线程实际上并不关心.

可调用:如果您尝试从任务中检索值,则使用Callable.现在可以自行调用不会起作用.你将需要一个围绕Callable的Future,并在future.get()上获取你的值.这里调用线程将被阻塞,直到Future返回结果,而结果又等待Callable的call()方法执行.

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

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



6> Aniket Thaku..:

Callable接口声明call()方法,你需要提供泛型作为Object call()的类型应该返回 -

public interface Callable {
    /**
     * 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;
}

Runnable另一方面,接口声明run()了在使用runnable创建一个Thread并在其上调用start()时调用的方法.你也可以直接调用run()但是只执行run()方法是同一个线程.

public interface Runnable {
    /**
     * When an object implementing interface Runnable is used 
     * to create a thread, starting the thread causes the object's 
     * run method to be called in that separately executing 
     * thread. 
     * 

* The general contract of the method run is that it may * take any action whatsoever. * * @see java.lang.Thread#run() */ public abstract void run(); }

总结一些值得注意的差异是

    一个Runnable而对象不返回结果Callable对象返回结果.

    Runnable对象可以抛出异常时,对象不能抛出已检查Callable的异常.

    Runnable接口自Java 1.0以来一直存在,而Callable仅在Java 1.5中引入.

几个相似之处包括

    实现Runnable或Callable接口的类的实例可能由另一个线程执行.

    ExecutorService可以通过submit()方法执行Callable和Runnable接口的实例.

    两者都是功能接口,可以在Java8之后的Lambda表达式中使用.

ExecutorService接口中的方法是

 Future submit(Callable task);
Future submit(Runnable task);
 Future submit(Runnable task, T result);



7> Ravindra bab..:

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

Runnable接口应由任何其实例要由a执行的类实现Thread.该类必须定义一个不带参数的方法run.

可调用:返回结果并可能抛出异常的任务.实现者定义一个没有名为call的参数的方法.该Callable接口类似于Runnable,在这两个被设计用于一个其实例潜在地由另一个线程执行.Runnable但是,A 不会返回结果,也不能抛出已检查的异常.

其他差异:

    您可以传递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();
        }
    
    }
    

    使用Runnable消防和忘记调用.使用Callable来验证结果.

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

    微不足道的差异:要实现的方法名称=> run()for Runnablecall()for Callable.



8> AlexR..:

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

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



9> Premraj..:
+-------------------------------------+--------------------------------------------------------------------------------------------------+
|              Runnable               |                                           Callable                                            |
+-------------------------------------+--------------------------------------------------------------------------------------------------+
| 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的设计者觉得需要扩展Runnable接口的功能,但他们不想影响Runnable接口的使用,这可能就是为什么他们选择Callable在Java 1.5中使用一个单独的接口而不是改变已经接口的原因.现有的Runnable接口,自Java 1.0以来一直是Java的一部分.资源



10> Raman Gupta..:

Callable和Runnable之间的区别如下:

    JDK 5.0中引入了Callable,而JDK 1.0中引入了Runnable。

    Callable具有call()方法,而Runnable具有run()方法。

    Callable具有可以返回值的call方法,而Runnable具有可以不返回任何值的run方法。

    调用方法可以引发检查异常,但运行方法不能引发检查异常。

    可调用的使用commit()方法放入任务队列,而Runnable的使用execute()方法放入任务队列。

推荐阅读
携手相约幸福
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有