前景提要
在 FutureTask 里面,普通写和 CAS 写是 混合使用的。比如 public boolean cancel(boolean mayInterruptIfRunning) { if (!(state == NEW && UNSAFE.compareAndSwapInt(this, stateOffset, NEW, mayInterruptIfRunning ? INTERRUPTING : CANCELLED))) return false; try { // in case call to interrupt throws exception if (mayInterruptIfRunning) { try { Thread t = runner; if (t != null) t.interrupt(); } finally { // final state UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED); //这里是普通写语义 } } } finally { finishCompletion(); } return true; }
我这么解释对吗: 一来,这个状态转移是唯一的。INTERRUPTING 只能变成 INTERRUPTED 。其他线程暂时看不到 INTERRUPTED 也没关系。(注意,暂时看不到 INTERRUPTING,会导致 handlePossibleCancellationInterrupt 自旋) 二来。由于 finishCompletion 有其他的 CAS 操作,执行了 CAS 操作就相当于强制刷新了内存,所以只要 finishCompletion 执行了 CAS,那么其他线程也就能看到 INTERRUPTED 这个状态了。