Volatile缓存可见性实现原理(JMM数据原子操作具体步骤)

Java内存模型:

在这里插入图片描述

JMM数据原子操作:

在这里插入图片描述

具体操作步骤:

在这里插入图片描述

线程1:先把initFlag变量read读取出来,再load载入工作内存,use使用线程1执行代码!initFlag

线程2:先把initFlag变量read读取出来,再load载入工作内存,use使用线程2执行代码initFlag=true,再assign重新赋值,store存储并写入主内存,write写入到主内存中的变量。(线程2对缓存行lock加锁,write写入主内存后会解锁unlock,防止initFlag还未write写入主内存就被线程1读取为false)。

线程1:因为initFlag被volatile修饰,使用MESI缓存一致性协议,线程1cpu总线嗅探机制监听到了initFlag值的修改,线程1中initFlag=false失效变为true退出循环继续执行,体现了多线程同步运行共享变量副本的可见性。如果initFlag没有被volatile修饰,线程1将感知不到initFlag的变化,一直循环下去停止不了。

图中的代码:

public class VolatileVisibilityTest {
    //volatile变量,用来确保将变量的更新操作通知到其他线程。
    private static volatile boolean initFlag = false;

    public static void main(String[] args) throws InterruptedException {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("waiting data...");
                while (!initFlag) {

                }
                System.out.println("==============success");
            }
        }).start();

        Thread.sleep(2000);

        new Thread(new Runnable() {
            @Override
            public void run() {
                prepareData();
            }
        }).start();
    }
        public static void prepareData(){
            System.out.println("preparing data...");
            initFlag = true;
            System.out.println("prepare data end...");
        }
}

解决jmm缓存不一致问题:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


总线加锁:
lock和unlock会对主内存加锁的,总线加锁一般不使用,效率太低,跟单线程差不多。一般用MESI缓存一致性协议。
在这里插入图片描述
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值