描述下场景:一个main方法中有2个线程,initFlag是布尔类型的共享变量。一个线程是对initFlag做取反的死循环,一旦initFlag为true就跳出死循环,执行打印success的操作;另一个线程修改initFlag为true,触发第一个线程跳出死循环。第一个线程启动之后sleep下确保在启动第二个线程时第一个已经进入死循环。
图中有一个主内存区,2个线程,每个线程有自己的工作内存,线程启动之后会从主内存中读取变量的副本存在工作内存中,通过read指令读取、load指令载入工作内存。第二个线程会对initFlag取反操作,通过use指令读取工作内存的变量,通过assign指令进行计算,把计算的新值赋值给工作内存的变量赋值。若是共享变量是volatile声明的,就会把新值立即回写到主内存,通过store指令读取工作内存的变量传入到主内存,然后在主内存中通过write指令给变量赋值。
回写时底层通过lock前缀指令执行锁定这块内存区域的缓存(缓存行锁定),然后执行store指令,这里需要注意的是所有的读写请求都通过总线,由总线传递给所有的CPU。其他CPU通过总线嗅探和缓存一致性协议来保证数据的一致性。具体是由每个CPU通过总线嗅探机制会监听自己工作内存中存在的变量,一旦发生回写,缓存一致性协议会使得其他CPU里缓存了改内存地址的数据无效,当其他CPU需要回写或者使用时会重新从内存中读取。在回写到主内存完成之后会执行unlock指令,提供给其他CPU使用。简单的说就是所有的读写请求都通过总线传递给所有的CPU,然后CPU去“嗅探”这些请求,当感知到数据变化时将自己的缓存的数据置为失效。