java中Runnable和Callable的区别
2020/3/11 17:01:37
本文主要是介绍java中Runnable和Callable的区别,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
java中Runnable和Callable的区别
在java的多线程开发中Runnable一直以来都是多线程的核心,而Callable是java1.5添加进来的一个增强版本。
本文我们会详细探讨Runnable和Callable的区别。
运行机制
首先看下Runnable和Callable的接口定义:
@FunctionalInterface 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(); } 复制代码
@FunctionalInterface 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; } 复制代码
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(),就可以获取到包含在里面的具体异常信息。
本文的例子可以参考github.com/ddean2009/l…
更多教程请参考 flydean的博客
这篇关于java中Runnable和Callable的区别的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-10-01基于Python+Vue开发的医院门诊预约挂号系统
- 2024-10-01基于Python+Vue开发的旅游景区管理系统
- 2024-10-01RestfulAPI入门指南:打造简单易懂的API接口
- 2024-10-01初学者指南:了解和使用Server Action
- 2024-10-01Server Component入门指南:搭建与配置详解
- 2024-10-01React 中使用 useRequest 实现数据请求
- 2024-10-01使用 golang 将ETH账户的资产平均分散到其他账户
- 2024-10-01JWT用户校验课程:从入门到实践
- 2024-10-01Server Component课程入门指南
- 2024-09-30Dnd-Kit学习:新手快速入门指南