Java多线程之Callable和Future

Java多线程之Callable和Future

callable出现的原因:
    创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口。这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果。
    如果需要获取执行结果,就必须通过共享变量或者使用线程通信的方式来达到效果,这样使用起来就比较麻烦。
    Callable接口类似于Runnable,从名字就可以看出来了,但是Runnable不会返回结果,并且无法抛出返回结果的异常,而Callable功能更强大一些,被线程执行后,可以返回值,这个返回值可以被Future拿到,也就是说,Future可以拿到异步执行任务的返回值。
    Callable接口提供了一个call()方法作为可以执行的线程体,但是call()方法比run()方法更强大。

  • call()方法有返回值
  • call()方法可以抛出异常

    因此完全可以提供一个Callable对象作为Thread的target,而该线程的线程执行体就是该callable对象的call方法。问题是 :Callable接口是Java 5新增的接口,而且他不是Runnable接口的子接口,所以Callable对象不能直接作为Thread的target。而且call方法他有一个返回值————call方法并不是直接调用,它是作为线程的执行体被调用。哪吗如何获得call接口的返回值呢?
    Java5提供了Future接口来代表Callable接口里的call方法的返回值,并为Future接口提供了一个Future提供了一个FutureTask实现类,该类实现了Future接口和Runable接口——可以作为Thread的target。

  • boolean cancel(boolean mayInterruptIfRunning)
    • 试图取消对此任务的执行。如果任务已完成、或已取消,或者由于某些其他原因而无法取消,则此尝试将失败。当调用 cancel 时,如果调用成功,而此任务尚未启动,则此任务将永不运行。如果任务已经启动,则 mayInterruptIfRunning 参数确定是否应该以试图停止任务的方式来中断执行此任务的线程。
      • 此方法返回后,对 isDone() 的后续调用将始终返回 true。如果此方法返回 true,则对 isCancelled() 的后续调用将始终返回 true。
      • 参数:mayInterruptIfRunning - 如果应该中断执行此任务的线程,则为 true;否则允许正在运行的任务运行完成
      • 返回:如果无法取消任务,则返回 false,这通常是由于它已经正常完成;否则返回 true
    • boolean isCancelled()如果在任务正常完成前将其取消,则返回 true。

      • 返回:如果任务完成前将其取消,则返回 true
    • boolean isDone()如果任务已完成,则返回 true。 可能由于正常终止、异常或取消而完成,在所有这些情况中,此方法都将返回 true。

      • 返回:如果任务已完成,则返回 true
    • V get()
      throws InterruptedException,
      ExecutionException如有必要,等待计算完成,然后获取其结果。

      • 返回:计算的结果
      • 抛出:
        CancellationException - 如果计算被取消
        ExecutionException - 如果计算抛出异常
        InterruptedException - 如果当前的线程在等待时被中断
    • V get(long timeout,
      TimeUnit unit)
      throws InterruptedException,
      ExecutionException,
      TimeoutException如有必要,最多等待为使计算完成所给定的时间之后,获取其结果(如果结果可用)。

      • 参数:
        timeout - 等待的最大时间
        unit - timeout 参数的时间单位
      • 返回:计算的结果
      • 抛出:
        CancellationException - 如果计算被取消
        ExecutionException - 如果计算抛出异常
        InterruptedException - 如果当前的线程在等待时被中断
        TimeoutException - 如果等待超时

下面来看一个简单的例子:

public class CallableAndFuture {
    public static void main(String[] args) {
        Callable<Integer> callable = new Callable<Integer>() {
            public Integer call() throws Exception {
                return new Random().nextInt(100);
            }
        };
        FutureTask<Integer> future = new FutureTask<Integer>(callable);
        new Thread(future).start();
        try {
            Thread.sleep(5000);// 可能做一些事情
            System.out.println(future.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值