Callable和Future

原文链接  译文链接 译者:Greenster 校对:沈义扬

Java从发布的第一个版本开始就可以很方便地编写多线程的应用程序,并在设计中引入异步处理。Thread类、Runnable接口和Java内存管理模型使得多线程编程简单直接。但正如之前提到过的,Thread类和Runnable接口都不允许声明检查型异常,也不能定义返回值。没有返回值这点稍微有点麻烦。

 不能声明抛出检查型异常则更麻烦一些。public void run()方法契约意味着你必须捕获并处理检查型异常。即使你小心地保存了异常信息(译者注:在捕获异常时)以便稍后检查,但也不能保证这个类(译者注:Runnable对象)的所有使用者都读取异常信息。你也可以修改Runnable实现的getter,让它们都能抛出任务执行中的异常。但这种方法除了繁琐也不是十分安全可靠,你不能强迫使用者调用这些方法,程序员很可能会调用join()方法等待线程结束然后就不管了。

但是现在不用担心了,以上的问题终于在1.5中解决了。Callable接口和Future接口的引入以及他们对线程池的支持优雅地解决了这两个问题。

Callable

Callable接口定义了方法public T call() throws Exception。我们可以在Callable实现中声明强类型的返回值,甚至是抛出异常。尽管在Executors类中已经有一些方法可以将Runnable对象转换为Callable对象,你最好还是仔细复审现有的Runnable实现或Thread的子类。为什么还要这样做?主要是为了检查和清除因为Runnable无法抛出检查型异常而采用的变通方案。同时,你可能希望利用call()方法直接返回结果的能力,以省去读取值时的类型转换。

Future

下面就将线程池和Callable接口相结合,看能发生怎样的效应。FutureJava 1.5中引入的接口,当你提交一个Callable对象给线程池时,将得到一个Future对象,并且它和你传入的Callable有相同的结果类型声明。这个对象取代了Java 1.5之前直接操作具体Thread实例的做法。过去你不得不用Thread.join()或者Thread.join(long millis)等待任务完成,而现在你可以像下面的例子那样做。

01

public class ServerAcceptingRequestsVerifier implements Callable {

02

    /**

03

     * @return Boolean.TRUE is server is accepting requests

04

     * Boolean.FALSE otherwise

05

     */

06

    public Boolean call() throws Exception {

07

        Boolean isAcceptingRequests = null;

08

        ... ask server about taking requests here

09

        return isAcceptingRequests;

10

    }

11

}

12

public Boolean isServerTakingRequests(String server)

13

            throws UnresponsiveException, InterruptedException {

14

    ServerAcceptingRequestsVerifier acceptingRequestsVerifier =

15

        new ServerAcceptingRequestsVerifier();

16

    Future future =

17

        THREAD_POOL.submit(acceptingRequestsVerifier);

18

    try {

19

        Boolean isAcceptingRequests = future.get();

20

        //waits for the thread to complete, even if it hasn't started

21

        return isAcceptingRequests;

22

    } catch (ExecutionException e) {

23

        throw new UnresponsiveException(e.getCause());

24

    }

25

26

}

如果要限制等待任务结束的时间,也可以添加一个捕获TimeoutExceptioncatch子句

01

try {

02

    Boolean isAcceptingRequests = future.get(5, TimeUnit.SECONDS);

03

    //this waits for 5 seconds, throwing TimeoutException if not done

04

    return isAcceptingRequests;

05

catch (TimeoutException e) {

06

    LOGGER.warn("Timed out waiting for server check thread." +

07

        "We'll try to interrupt it.");

08

    future.cancel(true);

09

    return Boolean.FALSE;

10

catch (ExecutionException e) {

11

    throw new UnresponsiveException(e.getCause());

12

}

转载自并发编程网 – ifeve.com本文链接地址: CallableFuture

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值