600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > Java多线程之FutureTask

Java多线程之FutureTask

时间:2021-12-16 22:57:09

相关推荐

Java多线程之FutureTask

一:FutureTask是什么?

创建线程的方式,一般是通过继承Thread或者实现Runnable接口实现,在线程运行结束后如果想获取返回结果,可以使用Handler等实现线程间通讯。而FutureTask可以在运行结束之后直接返回结果。

二:FutureTask结构

三:示例

FutureTask<Integer> futureTask = new FutureTask<Integer>(new Callable<Integer>(){@Overridepublic Integer call() throws Exception {// 线程开始int count = 0;for (int i = 0; i < 100; i++) {count += i;}Thread.sleep(3000);// 线程结束,返回结果return count;}});// 新建线程,执行futureTasknew Thread(futureTask).start();try {// 获取返回结果,如果futureTask没有运行结束,则会堵塞当前线程等待int result = futureTask.get();Log.i("testLog", "The result is " + result);} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}复制代码

源码分析

FutureTask.java

// 状态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<V> callable;// 执行结果,也可以是异常信息private Object outcome; // non-volatile, protected by state reads/writes// 当前运行的线程,用于保证run只执行一次private volatile Thread runner;// 任务未执行完成时,等待队列private volatile WaitNode waiters;// 构造函数public FutureTask(Callable<V> callable) {if (callable == null)throw new NullPointerException();this.callable = callable;this.state = NEW; // ensure visibility of callable}// 构造函数,传入的Runnable和返回结果public FutureTask(Runnable runnable, V result) {this.callable = Executors.callable(runnable, result);this.state = NEW; // ensure visibility of callable}// 是否取消public boolean isCancelled() {...}// 是否被执行public boolean isDone() {...}// 取消任务public boolean cancel(boolean mayInterruptIfRunning) {...}// 获取结果public V get() {...}// 获取结果,如果在给定时间内没有执行完成,抛出超时异常public V get(long timeout, TimeUnit unit) {...}// 执行public void run() {...}复制代码

run()方法

public void run() {// 1. 状态如果不是NEW,说明任务或者已经执行过,或者已经被取消,直接返回// 2. 状态如果是NEW,则尝试把当前执行线程保存在runner字段中// 如果赋值失败则直接返回if (state != NEW ||!pareAndSwapObject(this, RUNNER, null, Thread.currentThread()))return;try {Callable<V> c = callable;if (c != null && state == NEW) {V result;boolean ran;try {// 执行Callable的call方法,并获取返回结果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);}}复制代码

get()方法

public V get() throws InterruptedException, ExecutionException {int s = state;if (s <= COMPLETING)// 未执行完成,则等待s = awaitDone(false, 0L);return report(s);}private int awaitDone(boolean timed, long nanos)throws InterruptedException {long startTime = 0L; // Special value 0L means not yet parkedWaitNode q = null;boolean queued = false;for (;;) {int s = state;// 已完成,异常或者被取消。if (s > COMPLETING) {if (q != null)q.thread = null;return s;}// 已完成,让出线程优先权else if (s == COMPLETING)Thread.yield();// 线程被打断,移除等待队列,并抛出异常else if (Thread.interrupted()) {removeWaiter(q);throw new InterruptedException();}// 如果等待队列为空,则创建一个else if (q == null) {if (timed && nanos <= 0L)return s;q = new WaitNode();}// 如果还没有入队列,则把当前节点加入waiters首节点并替换原来waiterselse if (!queued)queued = pareAndSwapObject(this, WAITERS,q.next = waiters, q);// 需要等待,则计算等待时间else if (timed) {final long parkNanos;if (startTime == 0L) { // first timestartTime = System.nanoTime();if (startTime == 0L)startTime = 1L;parkNanos = nanos;} else {long elapsed = System.nanoTime() - startTime;if (elapsed >= nanos) {removeWaiter(q);return state;}parkNanos = nanos - elapsed;}if (state < COMPLETING)LockSupport.parkNanos(this, parkNanos);}elseLockSupport.park(this);}}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);}复制代码

任务取消

public boolean cancel(boolean mayInterruptIfRunning) {if (!(state == NEW &&pareAndSwapInt(this, STATE, NEW,mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))return false;try { // 打断线程 if (mayInterruptIfRunning) {try {Thread t = runner;if (t != null)// interrupt()方法只是设置中断标志位//如果被中断的线程处于sleep()、wait()或者join()逻辑中则会抛出InterruptedException异常。t.interrupt();} finally { // final stateU.putOrderedInt(this, STATE, INTERRUPTED);}}} finally {finishCompletion();}return true;}// 唤醒所有等待线程,移除所有等待队列private void finishCompletion() {// assert state > COMPLETING;for (WaitNode q; (q = waiters) != null;) {if (pareAndSwapObject(this, WAITERS, q, null)) {for (;;) {Thread t = q.thread;if (t != null) {q.thread = null;LockSupport.unpark(t);}WaitNode next = q.next;if (next == null)break;q.next = null; // unlink to help gcq = next;}break;}}done();callable = null; // to reduce footprint}复制代码

五:小结

FutureTask是可以被线程执行并获取返回执行结果的。其他线程在获取FutureTask的执行结果时,如果FutureTask未执行结束,则会被堵塞等待的。FutureTask调用cancel(true)并不一定能停止当前的线程。

参考:

深入学习FutureTask

Java并发学习(四)-sun.misc.Unsafe

UML画图工具-Graphviz和PlantUML

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。