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(),就可以获取到包含在里面的具体异常信息。
本文的例子可以参考https://github.com/ddean2009/learn-java-concurrency/tree/master/runnable-callable
更多教程请参考 flydean的博客
java中Runnable和Callable的区别的更多相关文章
- Java线程—-Runnable和Callable的区别和联系
Java 提供了三种创建线程的方法 1.继承Thread接口 public class Thread2Thread { public static void main(String[] args) { ...
- Java中Runnable和Thread的区别
在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类是在java.lang包中定义的.一个类只要继承了Thread类同时覆写了本类中的run() ...
- Java中Runnable和Thread的区别(转)
http://developer.51cto.com/art/201203/321042.htm 第一种方式:使用Runnable接口创建线程 第二种方式:直接继承Thread类创建对象 使用Runn ...
- Runnable和Callable 的区别
Runnable和Callable 的区别 01.Runnable接口中只有一个run()没有返回值 没有声明异常 Callable接口中只有一个call()有返回值 有声明异常 02.Calla ...
- Java中Set Map List 的区别
java中set map list的区别: 都是集合接口 简要说明 set --其中的值不允许重复,无序的数据结构 list --其中的值允许重复,因为其为有序的数据结构 map--成对的数据结构 ...
- Java中Comparable和Comparator接口区别分析
Java中Comparable和Comparator接口区别分析 来源:码农网 | 时间:2015-03-16 10:25:20 | 阅读数:8902 [导读] 本文要来详细分析一下Java中Comp ...
- 转:Java中abstract和interface的区别
转自:Java中abstract和interface的区别 abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制,正是由于这两种机制的存在,才赋予了Java ...
- Java中this与super的区别【6】
若有不正之处,请多多谅解并欢迎批评指正,不甚感激.请尊重作者劳动成果: 本文原创作者:pipi-changing本文原创出处:http://www.cnblogs.com/pipi-changing/ ...
- Java中堆和栈的区别(转)
栈与堆都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. Java的堆是一个运行时数据区,类的对象从中分配空间.这些对象通过new. ...
随机推荐
- Python第十三章-网络编程
网络编程 一.网络编程基础 python 的网络编程模块主要支持两种Internet协议: TCP 和 UDP. 1.1通信协议 通信协议也叫网络传输协议或简称为传送协议(Communications ...
- Q - Queue HDU - 5493(树状树组维护区间前缀和 + 二分找预留空位)
Q - Queue HDU - 5493 Problem Description NNN people numbered from 1 to NNN are waiting in a bank for ...
- RocketMQ 源码分析之路由中心(NameServer)
你可能没有看过 RocketMQ 的架构图,没关系,一起来学习一下,RocketMQ 架构图如下: 在 RocketMQ 中,有四个角色: Producer:消息的生产者,每个 MQ 中间件都有. C ...
- .git/info/refs not valid: is this a git repository?
今天用idea git提交的时候遇到了这个神奇的问题.git/info/refs not valid: is this a git repository? 看了很多网上的都不靠谱,最后自己乱点着找, ...
- session分布式处理
session分布式处理 标签(空格分隔): 分布式 1. Session复制 在支持Session复制的Web服务器上, 通过修改服务器配置, 可以实现将Session同步到其它Web服务器上, 达 ...
- springboot 切面添加日志功能
1.新建一个springboot项目 2.定义个切面类,并指定切入点,获取所需记录信息(如:访问人IP, 访问地址,访问地址名称等) 3.新建数据库 SET FOREIGN_KEY_CHECKS=0; ...
- 最小生成树算法【图解】--一文带你理解什么是Prim算法和Kruskal算法
假设以下情景,有一块木板,板上钉上了一些钉子,这些钉子可以由一些细绳连接起来.假设每个钉子可以通过一根或者多根细绳连接起来,那么一定存在这样的情况,即用最少的细绳把所有钉子连接起来. 更为实际的情景是 ...
- python 函数--装饰器
一.装饰器 1.为什么要用装饰器? 装饰器的功能:在不修改原函数以及调用方式的情况下对原函数功能进行扩展. 二.开放和封闭原则 1.对扩展是开放的 2.对修改是封闭的 三.装饰器的固有结构 impor ...
- dp优化---四边形不等式与决策单调性
四边形不等式 定理1: 设w(x,y)为定义在整数集合上的二元函数,若存在任意整数a,b,c,d(a<=b<=c<=d),并且w(a,d)+w(b,c)>=w(a,c)+w(b ...
- Linux忘记密码解决方案
Linux 忘记密码解决方法 很多朋友经常会忘记Linux系统的root密码,linux系统忘记root密码的情况该怎么办呢?重新安装系统吗?当然不用!进入单用户模式更改一下root密码即可. 步骤如 ...