FutureTask源码分析

1.源码带中文注解

package com.xmg.thread;

import java.util.concurrent.*;
import java.util.concurrent.locks.LockSupport;

/**
 * 可取消的异步运算。此类提供了对{@link Future}的基本实现,分别通过
 * 开始和取消一个运算的方法,查询是否运算完成,获取运算结果。只有当
 * 运算完成时才能获取结果。如果运算尚未完成,{@code get}方法将会阻塞。
 * 一旦运算完成,运算将不会重新开始或者取消(除非运算被{@link #runAndReset}打断}
 *
 * <p>一个{@code FutureTask}可以被用来包装{@link Callable}或者{@link Runnable} 对象。
 * 因为{@code FutureTask}实现了{@code Runnable},所以可以将{@code FutureTask}
 * 提交给{@link Executor}执行
 *
 * <p>除了作为一个独立的类外,该类提供了{@code protected}功能,这在创建自定义任务类时可能有用。
 *
 * @since 1.5
 * @author Doug Lea
 * @param <V> 该FutureTask的 {@code get} 的结果返回值类型
 */
public class FutureTask<V> implements RunnableFuture<V> {
	/*
	 * 修订记录:该类和上一个版本的区别依赖于AbstractQueuedSynchronizer
	 * 主要用来避免让读者对在取消竞态阶段保留中断状态而感到惊讶。
	 * 同步控制在当前设计中依赖于状态字段,通过CAS更新来跟踪完成,和一个
	 * 简单的Treiber栈来保存等待的线程。
	 *
	 * 风格记录:与往常类似,我们绕过了使用AtomicXFieldUpdaters的开销,
	 * 而是直接使用Unsafe的内部函数。
	 */

	/**
	 * 该任务的运行状态,初始状态为NEW。
	 * 运行状态仅通过set,setException, cancel方法转变到终端状态。
	 * 在运算过程中,状态会短暂的为COMPLETING(当outcome准备set时)
	 * 或者INTERRUPTING(仅当中断了runner来满足cancel(true))。从这
	 * 些中间状态到最终状态的转换使用了成本更低的有序/懒惰的写操作,
	 * 因为值是惟一的并且不能进一步修改。
	 *
	 * 状态之间可能的转换:
	 * NEW -> COMPLETING -> NORMAL
	 * NEW -> COMPLETING -> EXCEPTIONAL
	 * NEW -> CANCELLED
	 * NEW -> INTERRUPTING -> INTERRUPTED
	 */
	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;

	/** 底层的 callable; 运行后为null */
	private Callable<V> callable;
	/** get()返回的或异常抛出的结果 */
	private Object outcome; // 非volatile, 通过state的reads/writes保护
	/** 运行这个 callable的线程; 在run()方法中CAS运算 */
	private volatile Thread runner;
	/** 等待线程的Treiber 栈 */
	private volatile WaitNode waiters;

	/**
	 * 任务结束后返回结果或者抛出异常
	 *
	 * @param s 完成状态值
	 */
	@SuppressWarnings("unchecked")
	private V report(int s) throws ExecutionException {
		Object x = outcome;
		//正常结束,返回x(x是callable执行的结果outcome)
		if (s == NORMAL)
			return (V)x;
		//如果被取消,则抛出已取消异常
		if (s >= CANCELLED)
			throw new CancellationException();
		throw new ExecutionException((Throwable)x);
	}

	/**
	 * 创建一个 {@code FutureTask} 将会运行时执行给定的{@code Callable}
	 *
	 * @param  callable callable任务
	 * @throws NullPointerException 如果callable是null
	 */
	public FutureTask(Callable<V> callable) {
		if (callable == null)
			throw new NullPointerException();
		this.callable = callable;
		this.state = NEW;       // 确保callable的可见性
	}

	/**
	 * 创建一个 {@code FutureTask} 将会运行时执行给定的{@code Callable},
	 * 并且安排{@code get}在成功完成时将返回给定的结果。
	 *
	 * @param runnable runnable 任务
	 * @param result 成功完成后返回的结果。如果你不需要一个特殊的结果,
	 *                  考虑使用以下形式的结构:
	 * {@code Future<?> f = new FutureTask<Void>(runnable, null)}
	 * @throws NullPointerException 如果runnable为null
	 */
	public FutureTask(Runnable runnable, V result) {
		this.callable = Executors.callable(runnable, result);
		this.state = NEW;       // 保证callable的可见性
	}

	public boolean isCancelled() {
		return state >= CANCELLED;
	}

	public boolean isDone() {
		return state != NEW;
	}

	public boolean cancel(boolean mayInterruptIfRunning) {
		//判断状态:只有刚创建才能取消
		//mayInterruptIfRunning: 是否中断当前正在运行这个FutureTask的线程
		if (!(state == NEW &&
				UNSAFE.compareAndSwapInt(this, stateOffset, NEW,
						mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
			return false;
		try {
			//如果中断当前线程,则对runner发布interrupt信号
			if (mayInterruptIfRunning) {
				try {
					Thread t = runner;
					if (t != null)
						t.interrupt();
				} finally { // final state
					//修改状态为:已经通知线程中断。
					UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);
				}
			}
		} finally {
			//通知其他在等待结果的线程
			finishCompletion();
		}
		return true;
	}

	/**
	 * @throws CancellationException {@inheritDoc}
	 */
	public V get() throws InterruptedException, ExecutionException {
		int s = state;
		//如果还没执行完,则等待
		if (s <= COMPLETING)
			s = awaitDone(false, 0L);
		//通过report取结果
		return report(s);
	}

	/**
	 * @throws CancellationException {@inheritDoc}
	 */
	public V get(long timeout, TimeUnit unit)
			throws InterruptedException, ExecutionException, TimeoutException {
		if (unit == null)
			throw new NullPointerException();
		int s = state;
		if (s <= COMPLETING &&
				(s = awaitDone(true, unit.toNanos(timeout))) <= COMPLETING)
			throw new TimeoutException();
		return report(s);
	}

	/**
	 * 当该任务转换为{@code isDone}(不管是正常还是取消)状态,
	 * 这个保护的方法被调用。默认的实现不做任何事情。子类可以覆盖
	 * 该方法来调用完成回调或者记账。注意你可以查询该方法的实现状
	 * 态来确定该任务是否被取消了。
	 */
	protected void done() { }

	/**
	 * 设置该future的结果为给定的值除非该future已经被设置或已经被取消。
	 *
	 * <p>成功完成运算后,该方法在内部被{@link #run}方法调用。
	 *
	 * @param v 值
	 */
	protected void set(V v) {
		if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
			outcome = v;
			UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
			finishCompletion();
		}
	}

	/**
	 * 导致这个future报告一个{@link ExecutionException}异常,并将
	 * 给定的throwable作为其原因,除非该future已经设置或者已经取消。
	 *
	 * <p>运算失败后,该方法被{@link #run} 方法内部调用
	 *
	 * @param t 失败的原因
	 */
	protected void setException(Throwable t) {
		if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
			outcome = t;
			UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL); // final state
			finishCompletion();
		}
	}

	public void run() {
		//判断状态及设置futuretask归属的线程
		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 {
					//执行Callable
					result = c.call();
					//标记为执行成功
					ran = true;
				} catch (Throwable ex) {
					result = null;
					//标记为不成功
					ran = false;
					//设置为异常状态,并通知其他在等待结果的线程
					setException(ex);
				}
				if (ran)
					//如果执行成功,修改状态为正常,并通知其他在等待结果的线程
					set(result);
			}
		} finally {
			// runnner必须不为null直到解决了阻止对run()的并发调用的状态
			runner = null;
			//避免中断泄漏,在runner为null后状态必须为re-read
			int s = state;
			if (s >= INTERRUPTING)
				handlePossibleCancellationInterrupt(s);
		}
	}

	/**
	 * 无需设置结果执行这个运算,之后设置该future为初始状态,如果运算
	 * 遭遇一个异常或者取消将无法执行。本质上这是为执行多次任务而设计的。
	 *
	 * @return {@code true} 如果成功run或者reset
	 */
	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;
	}

	/**
	 * 确保来自可能的取消(true)的任何中断只在run或runAndReset时传递给任务。
	 *
	 */
	private void handlePossibleCancellationInterrupt(int s) {
		// 我们的中断器有可能在有机会打断我们之前停止。让我们耐心地循环等待。
		if (s == INTERRUPTING)
			while (state == INTERRUPTING)
				Thread.yield(); // 等待中断

		// assert state == INTERRUPTED;

		// 我们希望清除来自cancel(true)的任何中断。然而,使用中断作为任务与其
		// 调用者通信的独立机制是允许的,没有办法只清除取消中断。
		//
		// Thread.interrupted();
	}

	/**
	 * 简单的链表节点来记录在Treiber栈中等待线程。其他详细解释请
	 * 参考其他类似Phaser 和 SynchronousQueue
	 */
	static final class WaitNode {
		volatile Thread thread;
		volatile WaitNode next;
		WaitNode() { thread = Thread.currentThread(); }
	}

	/**
	 * 移除并通知所有等待的线程,调用done(),设置callable为null
	 */
	private void finishCompletion() {
		// assert state > COMPLETING;
		//遍历所有正在等待执行结果的线程
		for (WaitNode q; (q = waiters) != null;) {
			if (UNSAFE.compareAndSwapObject(this, waitersOffset, q, null)) {
				for (;;) {
					Thread t = q.thread;
					if (t != null) {
						q.thread = null;
						//unpark,发布一个让它继续执行的许可
						LockSupport.unpark(t);
					}
					WaitNode next = q.next;
					if (next == null)
						break;
					q.next = null; // 无链接帮助gc
					q = next;
				}
				break;
			}
		}

		done();

		callable = null;        // to reduce footprint
	}

	/**
	 * 等待完成或者中断或时间结束来中断
	 *
	 * @param timed true 如果使用了 timed 等待
	 * @param nanos 如果使用了timed,等待的时间
	 * @return 完成的状态
	 */
	private int awaitDone(boolean timed, long nanos)
			throws InterruptedException {
		//记录等待超时时间
		final long deadline = timed ? System.nanoTime() + nanos : 0L;
		//多个在等待结果的线程,通过一个链表进行保存,waitNode就是每个线程在链表中的节点
		WaitNode q = null;
		boolean queued = false;
		//死循环-自旋锁同步
		for (;;) {
			//判断当前这个调用get的线程是否被中断
			if (Thread.interrupted()) {
				//将当前线程移出队列
				removeWaiter(q);
				throw new InterruptedException();
			}

			int s = state;
			//如果状态非初创或执行完毕了,跳出循环,通过report()取执行结果
			if (s > COMPLETING) {
				if (q != null)
					q.thread = null;
				return s;
			}
			//如果状态等于已执行,让出cpu执行,等待状态变为正常结束
			else if (s == COMPLETING) // cannot time out yet
				Thread.yield();
			//如果当前线程还没有创建对象的waitNode节点,则创建一个
			else if (q == null)
				q = new WaitNode();
			//如果当前线程对应的waitNode还没有加入等待链表中,则加入进去。
			else if (!queued)
				queued = UNSAFE.compareAndSwapObject(this, waitersOffset,
						q.next = waiters, q);
			//如果有设置等待超时时间,则通过parkNanos挂起当前线程,等待继续执行的信号
			else if (timed) {
				nanos = deadline - System.nanoTime();
				if (nanos <= 0L) {
					removeWaiter(q);
					return state;
				}
				LockSupport.parkNanos(this, nanos);
			}
			else
				//通过park挂起当前线程,等待task执行结束后给它发一个继续执行的信号(unpark)
				LockSupport.park(this);
		}
	}

	/**
	 * 尝试去断开一个超时的或者被中断的等待节点来避免累加垃圾。如果释放器
	 * 以任何方式遍历它们,它是无害的,那么他们被内部的节点无需CAS就可以
	 * 简单拆分。为了避免对已经删除的节点进行不拼接的影响,在出现明显的竞
	 * 争时将重新遍历该列表。当有很多节点时,这个速度会很慢,但是我们不希
	 * 望列表足够长来满足较高的开销方案。
	 */
	private void removeWaiter(WaitNode node) {
		if (node != null) {
			node.thread = null;
			retry:
			for (;;) {          // 重新开始removeWaiter race
				for (WaitNode pred = null, q = waiters, s; q != null; q = s) {
					s = q.next;
					if (q.thread != null)
						pred = q;
					else if (pred != null) {
						pred.next = s;
						if (pred.thread == null) // check for race
							continue retry;
					}
					else if (!UNSAFE.compareAndSwapObject(this, waitersOffset,
							q, s))
						continue retry;
				}
				break;
			}
		}
	}

	// Unsafe mechanics
	private static final sun.misc.Unsafe UNSAFE;
	private static final long stateOffset;
	private static final long runnerOffset;
	private static final long waitersOffset;
	static {
		try {
			UNSAFE = sun.misc.Unsafe.getUnsafe();
			Class<?> k = java.util.concurrent.FutureTask.class;
			stateOffset = UNSAFE.objectFieldOffset
					(k.getDeclaredField("state"));
			runnerOffset = UNSAFE.objectFieldOffset
					(k.getDeclaredField("runner"));
			waitersOffset = UNSAFE.objectFieldOffset
					(k.getDeclaredField("waiters"));
		} catch (Exception e) {
			throw new Error(e);
		}
	}

}

 

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页