堆栈结构

内存模型

保证互斥性和可见性
volatile变量的读写直接发生在主存,volatile关键字也会防止volatile变量附近的指令重排,保证变量的可见性:
FutureTask没有使用同步锁,而是使用volatile就保证了多线程访问下能拿到正确的结果。
public class FutureTask<V> implements RunnableFuture<V> {
// state transitions: 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;
/** The underlying callable; nulled out after running */
private Callable<V> callable;
/** The result to return or exception to throw from get() */
private Object outcome; // non-volatile, protected by state reads/writes
/** The thread running the callable; CASed during run() */
private volatile Thread runner;
/** Treiber stack of waiting threads */
private volatile WaitNode waiters;
}这里只关注上面两个属性:
outcome = callable.call(),非volatile变量,state变量的读写会保护outcome变量的读取callable运行完成设置结果的逻辑是:
protected void set(V v) {
if (STATE.compareAndSet(this, NEW, COMPLETING)) {
outcome = v;
STATE.setRelease(this, NORMAL); // state变量写入之前会把outcome变量先写入到主存
finishCompletion();
}
}再看结果读取逻辑:
public V get() throws InterruptedException, ExecutionException {
int s = state;
if (s <= COMPLETING)
s = awaitDone(false, 0L);
return report(s); // 读取state变量之后,会读取到outcome的主存最新值
}
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);
}再比如AbstractQueuedSynchronizer也是用volatile保证同步块内变量的可见性。
单例模式懒加载的实现:
public class HeavyObject {
private HeavyObject() { // 构造函数私有
}
/**
* 多线程场景下,指令重排可能会导致新建对象先赋值给引用,但对象内部变量尚未初始化完成,其他线程拿到了未初始化完成的对象
* 加上volatile关键字防止指令重排
* */
private static volatile HeavyObject heavyObject;
public static HeavyObject getInstance() { // 获取单例
if (heavyObject == null) {
synchronized (HeavyObject.class) {
if (heavyObject == null) {
heavyObject = new HeavyObject();
}
}
}
return heavyObject;
}
}原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。