认识Future和FutureTask

什么是Future

Future是一个接口,在java.util.concurrent包下,官方注释解释Future表示异步计算的结果。其提供了一些方法来检查计算是否完成,等待其完成以及检索计算结果。计算完成后,只能使用方法get()方法检索结果,并在必要时阻塞,直到准备好为止。取消是通过cancel()方法执行的。提供了isCancelled()方法来确定任务是正常完成还是被取消。一旦计算完成,就不能取消计算。如果您想使用Future是为了可取消性但不提供可用的结果,则可以声明Future,并由于基础任务而返回null。

Future接口的方法

  • boolean cancel(boolean mayInterruptIfRunning);
    该方法传入一个boolean值,来确定执行该任务的线程是否应该中断;否则,正在进行的任务将被允许完成。
  • boolean isCancelled();
    如果此任务在正常完成之前被取消,则返回true
  • boolean isDone()
    如果此任务完成,则返回 true。完成可能是由于正常终止,异常或取消引起的,在所有这些情况下,此方法都将返回true。
  • V get() throws InterruptedException, ExecutionException;
    等待必要的计算完成,然后检索其结果。该方法会导致线程阻塞。
  • V get(long timeout, TimeUnit unit)
    throws InterruptedException, ExecutionException, TimeoutException;
    给定最多等待时间以完成计算,然后检索其结果(如果有)。

什么是FutureTask

该类实现了RunnableFuture接口,RunnableFuture接口又实现了Runnable, Future接口。此类提供Future的基本实现,返回异步执行的计算结果。具有启动和取消计算,查询以查看计算是否完成以及检索计算结果的方法。只有在计算完成后才能检索结果;如果计算尚未完成,则get方法将阻塞。一旦计算完成,就不能重新开始或取消计算(除非使用runAndReset调用计算)。

FutureTask的构造方法
 public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }

 public FutureTask(Runnable runnable, V result) {
        this.callable = Executors.callable(runnable, result);
        this.state = NEW;       // ensure visibility of callable
    }

传入Callable,则返回结果为Callable的计算结果,传入Runnable 则异步的返回值就是传入的result的值。两个构造函数都将设置FutureTask的初始状态置为NEW.

FutureTask的字段
  • state字段。标识FutureTask所处的状态。
    private volatile int state;
    private static final int NEW = 0;
    private static final int COMPLETING = 1;
    private static final int NORMAL = 2;
    private static final int EXCEPTIONAL = 3;
    private static final int CANCELLED = 4;
    private static final int INTERRUPTING = 5;
    private static final int INTERRUPTED = 6;
  • private Callable callable ;//任务
  • private Object outcome; //存储get()方法的返回值或异常
  • private volatile Thread runner;//执行任务的线程
  • private volatile WaitNode waiters;//get方法阻塞的线程队列
    FutureTask的方法
    • report方法
 private V report(int s) throws ExecutionException {
        Object x = outcome;
        if (s == NORMAL)
            return (V)x;
        if (s >= CANCELLED)
            throw new CancellationException();
        throw new ExecutionException((Throwable)x);
    }

get()方法中会调用report方法,report具体执行返回结果的功能。

  • set方法
protected void set(V v) {
        if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
            outcome = v;
            UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
            finishCompletion();
        }
    }

该方法可以设置异步结果的返回值。以代替任务执行的结果

  • runAndReset方法
protected boolean runAndReset() {
        if (state != NEW ||
            !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                         null, Thread.currentThread()))
            return false;
        boolean ran = false;
        int s = state;
        try {
            Callable<V> c = callable;
            if (c != null && s == NEW) {
                try {
                    c.call(); // don't set result
                    ran = true;
                } catch (Throwable ex) {
                    setException(ex);
                }
            }
        } finally {
            // runner must be non-null until state is settled to
            // prevent concurrent calls to run()
            runner = null;
            // state must be re-read after nulling runner to prevent
            // leaked interrupts
            s = state;
            if (s >= INTERRUPTING)
                handlePossibleCancellationInterrupt(s);
        }
        return ran && s == NEW;
    }

在不设置计算结果的情况下执行计算,然后将此Future状态重置为初始状态,如果计算遇到异常或被取消,则无法执行此操作。设计用于本质上执行多次的任务.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值