FutureTask
的线程安全是通过以下几种机制来保证的:
1. 内部状态的原子操作
FutureTask
存在内部状态来表示任务的执行状态,例如:NEW
、COMPLETING
、NORMAL
、EXCEPTIONAL
、CANCELLED
、INTERRUPTING
和 INTERRUPTED
。这些状态转换是通过使用 java.util.concurrent.atomic.AtomicInteger
类来原子地操作和更新的。这样的设计可以避免多个线程对状态进行非一致性修改,从而保证了状态更新的线程安全。
3. Lock
和 Condition
变量
在需要的时候,FutureTask
可能会使用 java.util.concurrent.locks.Lock
和 java.util.concurrent.locks.Condition
来实现更复杂的同步控制。例如, get()
方法可能会在任务未完成时阻塞等待,这时会利用 Condition
变量进行等待和通知(signal)。
4. volatile
关键字
核心成员变量通常使用 volatile
关键字进行修饰,确保变量的修改可以被其他线程立即看到。例如,任务状态通常会被设计为 volatile
,以确保状态变更对所有线程可见。
代码示例和关键部分
以下是 FutureTask
类中的一些关键代码片段,展示了其线程安全机制:
public class FutureTask<V> implements RunnableFuture<V> {
// 用于表示任务状态的 volatile 变量
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;
// Internal result holder, either a normal result or an exception
private Callable<V> callable;
private Object outcome; // non-volatile, protected by state reads/writes
private volatile Thread runner;
private volatile WaitNode waiters;
// 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 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
int s = state;
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
protected void set(V v) {
if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
outcome = v;
UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
finishCompletion();
}
}
protected void setException(Throwable t) {
if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
outcome = t;
UNSAFE.putOrderedInt(this, stateOffset, EXCEPTIONAL); // final state
finishCompletion();
}
}
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;
LockSupport.unpark(t);
}
WaitNode next = q.next;
if (next == null)
break;
q.next = null; // unlink to help gc
q = next;
}
break;
}
}
done();
callable = null; // to reduce footprint
}
// 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 = 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);
}
}
}
上述代码展示了 FutureTask
如何通过原子操作、同步、以及其他并发控制机制来保证其线程安全。