我对触发内存屏障时发生的确切情况感到困惑,我认为这也用于获得与主内存的缓存一致性,但是我进行了测试,结果我认为是错误的。
我有2个线程,主线程和另一个线程,为简单起见,我将它们分别称为M和T。
情况1:完全符合我的预期
如果T正在等待NOT volatile共享变量,然后M更改了该值,则T可能不会看到更改(因为正在读取缓存),但是如果T激活了内存屏障,则缓存值将被更新为主内存和线程可以结束他的工作。
情况2:这不符合我的预期
注意:要创建此案例,您需要用threadAt.get();
注释该行,并用//mainAt.get();
将该行取消逗号
这种情况与第一种情况完全相同,但是内存屏障已在M中激活,我认为该内存屏障会将所有缓存与主内存一起上载,因此T会看到它,但事实并非如此,T陷入永远的循环。
有人可以解释一下这种记忆障碍的真实情况吗?
package aaa.testVisibility;
import java.util.concurrent.atomic.AtomicInteger;
class Worker implements Runnable {
@Override
public void run() {
AtomicInteger threadAt = new AtomicInteger(0); //<-- Used for activating memory barrier later
System.out.println("Waiting");
while (!TestVisibility01.go) {
threadAt.get(); // <-- memory barrier fired, COMMENT THIS LINE AND UNCOMMENT THE OTHER
}
System.out.println("Exiting thread");
}
}
public class TestVisibility01 {
public static boolean go = false;
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(new Worker());
AtomicInteger mainAt = new AtomicInteger(0);
t.start();
System.out.println("Main thread sleep");
Thread.sleep(2000);
go = true;
//mainAt.get(); // <-- memory barrier fired, UNCOMMENT THIS LINE AND COMMENT THE OTHER
System.out.println("Main thread restart");
t.join();
System.out.println("Main exit");
}
}