java-并发-源码-Future&FutureTask&Callable

java-并发-源码-Future&FutureTask&Callable

Runnable无法获取线程结果
Callable是为了获取线程结果

例子

主线程

    ExecutorService executor = Executors.newCachedThreadPool();
    Task task = new Task();
    Future<Integer> result = executor.submit(task);
    System.out.println("task运行结果"+result.get());

callalbe任务

class Task implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        System.out.println("子线程在进行计算");
        Thread.sleep(3000);
        int sum = 0;
        for(int i=0;i<100;i++)
            sum += i;
        return sum;
    }
}

submit过程

AbstractExecutorService的submit方法会调用ThreadPoolExecutor的execute用线程池执行任务

    public <T> Future<T> submit(Callable<T> task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task);
        execute(ftask);
        return ftask;
    }

newTaskFor创建FutureTask,然后执行这个FutureTask的run方法,任务开始了

  protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
        return new FutureTask<T>(callable);
    }

submit的结果ftask即是一个Callable又是一个Future,所以在主线程中可以作为返回值

FutureTask

run方法

   public void run() {
        if (state != NEW || !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                         null, Thread.currentThread()))
            return;
        try {
            Callable<V> c = callable;
            if (c != null && state == NEW) {
                V result;
                boolean ran;
                try {
                    result = c.call();
                    ran = true;
                } catch (Throwable ex) {
                    result = null;
                    ran = false;
                    setException(ex);
                }
                if (ran)
                    set(result);
            }
        } finally {
            runner = null;
            int s = state;
            if (s >= INTERRUPTING)
                handlePossibleCancellationInterrupt(s);
        }
    }

执行callable函数,然后result获取callable的返回值,调用set(result)将值设置到outcome上

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

Future的get方法,返回的就是outcome的值
因为每个任务都创建了一个FutureTask,所以不会有并发问题

posted @ 2016-09-22 21:12  zhangshihai1232  阅读(142)  评论(0)    收藏  举报