java callable_java中Runnable和Callable的区别

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

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

运行机制

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

@FunctionalInterface

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();

}

@FunctionalInterface

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()方法,Callable需要实现call()方法。

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

class Thread implements Runnable {

/* Make sure registerNatives is the first thing 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(),就可以获取到包含在里面的具体异常信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值