JMM内存模型笔记

哎 得快点找到工作

https://www.bilibili.com/video/BV1Et411n7Ro?from=search&seid=15449624913687152734

CPU其实有缓存的,比如windows

而java的JMM模型其实也就类似于CPU缓存模型:

或者可以这么说,工作内存就是CPU的缓存,线程C其实就是运行在CPU的,主内存就是第一张图的RAM

看如下代码:

package com.company;

public class Main {

    public static boolean initFlag = false;

    public static void main(String[] args) throws Exception {
	// write your code here

        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("prepare start");
        initFlag = true;
        System.out.println("prepare end");
    }
}

运行结果就是,success永远不会打出来,因为两个线程用到的其实是initFlag的副本,而第一个线程的副本一直都是false,解决办法就是在initFlag前面加上volatile,volatile用来保证线程之间(共享)变量的可见性,上面代码其实就对应下面的操作

具体read,load,等命令的含义如下:

 诸葛老师喜欢做总结,我也要多总结总结

针对上述JMM缓存不一致的问题,有两种方案

1.总线加锁

某个线程read的时候加锁lock,直到该线程write结束,才unlock,在这个过程中,其他线程无法read读取被lock的对象,直到对象被unlock,才能去read,这样自然能保持变量一致,但是性能很低

2.MESI 缓存一致性协议

多个CPU可读取同一个数据到高速缓存,当某一个CPU修改了缓存数据,会被立即同步到主内存,此时其他CPU通过CPU嗅探机制,可感知到数据变化,而将缓存数据失效

 加了volatile的字段,汇编操作室会给他加一个lock指令前缀,其实也就是给该字段加锁,写回到主存以后,再unlock,但是volatile的锁粒度,相比总线锁,粒度大大减小。lock的目的是为了防止其他CPU读取原来无效的值(initFlag = false),因为有可能initFlag还没来得及变成true,其他线程就去因为缓存失效而重新去主存读initFlag了,所以必须lock住

 lock指令的作用:

1. 会将当前处理器缓存行(工作内存)的数据立即写回到主内存

2. 写回操作会引起其他CPU缓存了该内存地址的数据无效

 学东西容易忘记,那么就要多做笔记,多画脑图

 并发编程三大特性

可见性、原子性、有序性

volatile可以保证可见性,有序性,但是不保证原子性

可见性,就是上面的CPU嗅探机制

有序性,就涉及到指令重排序,而加了volatile的字段,汇编不会对其进行重排序,也就保证了有序性,为什么不会进行重排序呢,因为和volatile字段相关的指令会加lock 前缀,而lock指令自带内存屏障,而cpu看到这个lock,指令重排就绝对不会把lock指令前面的代码排到lock后面去执行

内存屏障,happens-before和as-if-serial原则,具体还不知道

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值