FutureTask outcome与volatile底层原理

内容纲要

volatile底层happens-before实现的原理

  • volatile具备的可见性(happens-before)的底层实现通过内存屏障实现的

    内存屏障

屏障名称 指令 功能 添加位置
StoreStore(写-写) Store1;StoreStore;Store2 禁止重排序:一定是Store1的数据写出到主内存完成之后,才能让Store2及其之后的写出操作的数据,被其他线程看到 保证Store1执行写出去的数据,会强制刷新回到主内存中 volatile写操作前面插入一个StoreStore屏障
LoadLoad(读-读) Load1;LoadLoad;Load2 禁止重排序:一定是Load2的读取操作 一定不会重排到Load1之前 保证Load2在读取的时候,自己缓存内到对应的数据失效,Load2会去主内存中获取最新的数据 volatile读后面插入一个LoadLoad屏障
LoadStore(读-写) Load1;LoadStore;Store2 禁止重排序: 一定是Load1读取数据完成后,才能让Store2及其之后的写出操作的数据,被其他线程看到 volatile读后面插入一个LoadStore屏障
StoreLoad(写-读) Store1;StoreLoad;Load2 禁止重排序:一定是Store1的数据写出到主内存完成之后,才能让Load2来读取数据 同时保证: 强制把缓冲去的数据刷回到主内存中,让工作内存/CPU高速缓存当中缓存的数据失效,重新到主内存中获取新的数据 volatile斜后面插入一个StoreLoad屏障

protected void set(V v) {
1. if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) { 
2.     outcome = v;
3.     UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
4. }
}

protected void set(V v) {
StoreStore
1   UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)
StoreLoad
2   outcome = v
StoreStore
3   UNSAFE.putOrderedInt(this, stateOffset, NORMAL)
StoreLoad
}

//第一个StoreStore保证了第一行代码之前的所有写操作已经刷新到了主内存
//第一个StoreLoad保证了第一行代码的写操作已经刷新到了主内存中
//第二个StoreStore保证了第二行代码将值存储到了outcome并且刷新会主内存
//第二个StoreLoad强制把缓冲去的数据刷回到主内存中,让工作内存/CPU高速缓存当中缓存的数据失效,重新到主内存中获取新的数据

//get方法

public V get() throws InterruptedException, ExecutionException {
1. int s = state;
2. if (s <= COMPLETING)
3.    s = awaitDone(false, 0L);
4. return report(s);
}

public V get() throws InterruptedException, ExecutionException {
1 int s = state;
LoadLoad
LoadStore
2   if (s <= COMPLETING)
3   s = awaitDone(false, 0L);
4 return report(s);
}

//LoadLoad 保证第第二行代码在读取的时候,自己缓存内的相应数据失效,Load2会去主内存中获取自行的数据
//LoadStore 一定是第一行代码读取数据完成之后,才能让后面的代码的写操作被其他县城看到
THE END
分享
二维码
< <上一篇
下一篇>>