文章目录

    • 运行机制
    • 返回值的不同
    • Exception处理


java中Runnable和Callable的区别


在java的多线程开发中Runnable一直以来都是多线程的核心,而Callable是java1.5添加进来的一个增强版本。

本文我们会详细探讨Runnable和Callable的区别。

运行机制

首先看下Runnable和Callable的接口定义:

@FunctionalInterfacepublic 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();}

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

Runnable需要实现run()方法,Callable需要实现call()方法。

我们都知道要自定义一个Thread有两种方法,一是继承Thread,而是实现Runnable接口,这是因为Thread本身就是一个Runnable的实现:

class Thread implements Runnable {/* Make sure registerNatives is the first thing <clinit> does. */private static native void registerNatives();static {registerNatives();}...

所以Runnable可以通过Runnable和之前我们介绍的ExecutorService 来执行,而Callable则只能通过ExecutorService 来执行。

返回值的不同

根据上面两个接口的定义,Runnable是不返还值的,而Callable可以返回值。

如果我们都通过ExecutorService来提交,看看有什么不同:

  • 使用runnable
    public void executeTask() {ExecutorService executorService = Executors.newSingleThreadExecutor();Future future = executorService.submit(()->log.info("in runnable!!!!"));executorService.shutdown();}

  • 使用callable
    public void executeTask() {ExecutorService executorService = Executors.newSingleThreadExecutor();Future future = executorService.submit(()->{log.info("in callable!!!!");return "callable";});executorService.shutdown();}

虽然我们都返回了Future,但是runnable的情况下Future将不包含任何值。

Exception处理

Runnable的run()方法定义没有抛出任何异常,所以任何的Checked Exception都需要在run()实现方法中自行处理。

Callable的Call()方法抛出了throws Exception,所以可以在call()方法的外部,捕捉到Checked Exception。我们看下Callable中异常的处理。

 public void executeTaskWithException(){ExecutorService executorService = Executors.newSingleThreadExecutor();Future future = executorService.submit(()->{log.info("in callable!!!!");throw new CustomerException("a customer Exception");});try {Object object= future.get();} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();e.getCause();}executorService.shutdown();}

上面的例子中,我们在Callable中抛出了一个自定义的CustomerException。

这个异常会被包含在返回的Future中。当我们调用future.get()方法时,就会抛出ExecutionException,通过e.getCause(),就可以获取到包含在里面的具体异常信息。

本文的例子可以参考https://github.com/ddean2009/learn-java-concurrency/tree/master/runnable-callable

更多精彩内容且看:

  • 区块链从入门到放弃系列教程-涵盖密码学,超级账本,以太坊,Libra,比特币等持续更新
  • Spring Boot 2.X系列教程:七天从无到有掌握Spring Boot-持续更新
  • Spring 5.X系列教程:满足你对Spring5的一切想象-持续更新
  • java程序员从小工到专家成神之路(2020版)-持续更新中,附详细文章教程

更多教程请参考 flydean的博客

©著作权归作者所有:来自51CTO博客作者ddean2009的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. 为留言板添加字数实时统计与禁止超出功能; 2. 自选一些字符串和
  2. java中FutureTask的使用
  3. java并发中的Synchronized关键词
  4. 怎么break java8 stream的foreach
  5. java.util.concurrent简介
  6. java 8 stream中的Spliterator简介
  7. 怎么在java中创建一个自定义的collector
  8. java 8 stream reduce详解和误区
  9. 留言板,字符串和数组方法 ----0407

随机推荐

  1. 如果改变输入值,jQuery提交表单
  2. Kohana框架3.3 cookie设置两次
  3. angular.min.js:107 Error: [ng:areq] ht
  4. PHP多线程编程
  5. 使用AJAX将数据发送到.php文件,如何从中获
  6. 解决PHP导出大量数据时设置超链接的问题
  7. 为什么我们坚持选择用php
  8. PHP结合Redis来限制用户或者IP某个时间段
  9. PHP替换标签字符
  10. 单击保存按钮(PHP和MSQL)时如何保存记录列