java futuretask 源码_FutureTask源码解读

import java.util.concurrent.Callable;

import java.util.concurrent.ExecutionException;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Future;

public class TestFuture

{

public static void main(String[] args) throws InterruptedException, ExecutionException

{

final ExecutorService executor = Executors.newCachedThreadPool();

final Future future = executor.submit(new CallableTest());

System.out.println("continue working");

System.out.println(future.get());

}

}

class CallableTest implements Callable

{

@Override

public String call() throws Exception

{

Thread.sleep(5000);

return "Hello World!";

}

}

上面的代码很简单,定义了一个Callable对象,利用ExecutorService线程池将Callable对象提交到线程池当中去执行。

本文要详细讲述的就是JDK中怎么通过Future对象来等待任务结果并阻塞线程(get())、取消任务等对任务线程的控制。

---------------------------------------------------------------------------------------------------------------

当将Callable对象、Runnable对象通过ExecutorService当中的submit方法提交到线程池当中的时候,会返回一个Future的对象,通过Future对象可以拿到相应的返回结果

1)提交任务后,主线程是继续向下执行的,因为任务被异步线程去执行了

2)当任务仍未执行完的时候,如果任何一个线程调用Future对象的get()方法想获取返回值得时候,都会将线程阻塞,等任务执行完毕之后,返回结果,线程被唤醒重新执行。

3)这提供了一种共享锁的模型,很多线程都可以通过同一个Future对象阻塞在一个条件上

--------------------------------这种多个线程阻塞和唤醒是怎么做到的呢?----------------------

package java.util.concurrent;

public interface Future {

boolean cancel(boolean mayInterruptIfRunning);

boolean isCancelled();

V get() throws InterruptedException, ExecutionException;

V get(long timeout, TimeUnit unit)

throws InterruptedException, ExecutionException, TimeoutException;

}

我们看到Future其实只是一个接口,那么他的实现在哪里呢?

-------------------------------------------

在ExecutorService的实现类AbstractExeccutorService当中的submit(Callable callable)

实现中(submit的作用就是提交一个有返回值的任务给线程池,并且返回一个Future对象来处理返回结果)

public Future submit(Callable task) {

if (task == null) throw new NullPointerException();

RunnableFuture ftask = newTaskFor(task);

execute(ftask);

return ftask;

}

看到返回的是一个RunnableFuture对象,这个对象实现了Runnable和Future的接口

protected RunnableFuture newTaskFor(Callable callable) {

return new FutureTask(callable);

}

看到返回的是FutureTask对象其实,包裹了Callable对象

这样其实就可以理解了,FutureTask对象实现了Runnable和Future接口,将FutureTask这个Runnable对象丢到Execcutor线程池当中异步执行(execute(ftask))

最终执行FutureTask对象的run方法,可想而已,在run方法中调用了Callable对象的call方法,并且将返回值赋值给FutureTask对象的成员变量以便get方法获取。

--------------------------------------------

public void run() {

sync.innerRun();

}

果然我们在FutureTask的run方法中看到调用了Sync对象的innerRun()方法

void innerRun() {

if (!compareAndSetState(READY, RUNNING))

return;

runner = Thread.currentThread();

if (getState() == RUNNING) { // recheck after setting thread

V result;

try {

result = callable.call();

} catch (Throwable ex) {

setException(ex);

return;

}

set(result);

} else {

releaseShared(0); // cancel

}

}

private final class Sync extends AbstractQueuedSynchronizer

Sync对象是在FutureTask当中的内部类对象

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值