加餐 | 什么是数据的强、弱一致性?
加餐 | 什么是数据的强、弱一致性?
讲述:李良
时长07:54大小7.25M
Java 存储模型
重排序
Happens-before 规则
赞 12
提建议
精选留言(28)
- THROW2019-07-08老师您好,都说concurrenthashmap的get是弱一致性,但我不理解啊,volatile 修饰的变量读操作为什么会读不到最新的数据?
作者回复: 我们知道Node<k,v>以及Node<k,v>的value是volatile修饰的,所以在一个线程对其进行修改后,另一个线程可以马上看到。 如果是一个新Node,那么就不能马上看到,虽然Node的数组table被volatile修饰,但是这样只是代表table的引用地址如果被修改,其他线程可以立马看到,并不代表table里的数据被修改立马可以看到。
共 5 条评论39 - 明翼2019-07-10早看到就好了😁,老师请教下这么多知识点你是怎么记住的?
作者回复: 平时善于做笔记,除此之外,尝试将自己学到的知识点分享给其他人。
共 2 条评论16 - Liam2019-07-06老师好,请教一个问题: 文中举例,数据不一致是多核CPU的高速缓存不一致导致的,是否意味着单核CPU多线程操作就不会发生数据不一致呢
作者回复: 也会的,线程安全除了要保证可见性,还需要保证原子性、有序性。
共 4 条评论9 - 钱2019-09-10数据只要在不同的地方,且存在写操作就可能存在不一致性。不管是各级缓存中还是分布式集群中的某些节点中,都有类似的问题。线程间的数据一致性问题,由操作系统来去保证,分布式系统中的数据一致性问题由分布式协议的实现者去保证,不过确实不好弄,令人头疼。 给老师点赞,讲的很棒,不过知识真是太多了,感觉越学越多,买的专栏都学不完,不学是不行的不进则退,如果英语好就占优势了,可以直接学习第一手的学习资料。展开
作者回复: 坚持看英文文档,到最后你就能流利的读任何英文文档说明了
6 - 青梅煮酒2019-07-16老师,请问一下,每核CPU都有自己的L1和L2,那么L1和L2的主要区别是什么呢?为什么不能合到一起呢?
作者回复: L1\L2\L3三个缓存的作用和实现的技术是不一样的,L1的内存大小是非常有限的,所以很多时候在L1获取缓存数据的命中率非常低。为了提高CPU读取的速率,在L1没有命中的缓存,可以进入到L2进行获取,L2的容量要比L1大,但离CPU核心更远。但还是能提高CPU读取缓存数据的速率。
5 - Lost In The Echo...2019-07-06老师,请问强一致性和顺序一致性有什么区别吗?
作者回复: 顺序一致性是指单个线程的执行的顺序性,强一致性则指的是多个线程在全局时钟下的执行的顺序性。
4 - -W.LI-2019-07-06老师容我问一个很基础的问题!父类private的属性会被子类继承么?子类创建的时候JVM给子类分配内存的时候,我看书上有说父类的属性会排在子类前面有可能穿插。可是没写是否会给子类分配父类的私有属性内存空间。子类创建的时候,会默认调用父类的无参构造器。这时候就会实例化一个父类对象么?(如果父类没有无参构造器会报错或者需要显示调用父类的有参构造器)。如果每次实力子类对象的时候都会先创建一个父类对象的话,滥用继承。就会浪费很多内存是么?对象头就需要8字节了。展开
作者回复: 子类会继承父类的private属性,但子类无法直接访问到private属性; 子类创建时,不会创建一个父类对象的,只是调用了父类的构造函数初始化而已。
共 2 条评论4 - 菜菜2019-10-08针对老师对留言1的回复,我想问下老师,Node<k,v>中除了value被volatile修饰了,next也被volatile修饰了呀,这样如果是新增新的Node的话,其他线程也不可以看到吗?
作者回复: 获取节点时是通过key值获取,并不一定通过next获取,所以不能代表对应key值中的value是最新的
2 - 尔冬橙2019-09-21老师可以不可以讲一下threadlocal
作者回复: mark
2 - 云封2019-07-07老师,请问下,如果不存在操作共享变量的情况或者把共享产量存在redis中,多线程结果就不会发生由于指令重排而导致结果不一致的情况。
作者回复: 指令重排序不一定是由于共享变量导致的,这块需要结合具体的场景分析。
2 - InnerPeace2021-01-07对于顺序一致性有点疑问。如果是单线程,无论是读还是写,都是串行,所以任何一次读都能读到最近一次写,这是显而易见的,为什么叫顺序一致性呢?1
- GaGi2020-05-02老师,图中CPU多级缓存图中,L3缓存应该是多个CPU核心共用的
作者回复: 是的
1 - 鱼2019-10-25老师,我指出一个错误,时序图中最后flag=true不是false
作者回复: 收到,谢谢提醒
1 - -W.LI-2019-07-07老师好volatile+cas是强一致性么?。L1直接刷回主存,L2和L3需要做什么操作么?开头说每一级都是上一级的子集来着。
作者回复: cas+volatile可以解决单个变量的强一致性问题。
1 - 东方奇骥2019-07-06上面例子,flag加volatile修饰,根据happens before中的顺序性选择和volatile的原则,就能保证另一个线程读到写入的值了。
作者回复: 对的,volatile除了可以保证变量的可见性,可以阻止局部指令重排序。
1 - 杯莫停2022-07-27“CPU 缓存可以分为一级缓存(L1)、二级缓存(L2)和三级缓存(L3),每一级缓存中所储存的全部数据都是下一级缓存的一部分” 就是说L1中的数据在L2中也有一份?为什么要这么设计,L2存增量不就好了吗?
- Bumblebee2022-06-01我觉得concurrenthashmap的get是弱一致性,可以这么理解,写操作是加锁的,get操作是无锁的,因此get操作有可能拿到写操作的中间值,因此是弱一致性(尽管volatile保证了可见性); 希望老师能点评一下,不知道这样理解对不对;展开
- Only now2020-11-03关于存储模型这一节,通过实验结果很难接受。还请老师解答。 在实验中,非volatile共享堆变量,是一个bool值, 使用x86_64机器, Oracle jdk 1.8进行测试。 extern boolean stop = false; new Thread(()->{ while(!stop){} System.out.println("over"); }).start(); System.sleep(100L); stop = true; 这样一段代码实际上不会停下来。按照三级缓存的这个说法,当内核在进行线程调度时会失效缓存,所以当线程被再次调入执行,它就应该可以看到stop更改的值,因为这个时候缓存已经更换过了。 然而事实并不会发现打印输出并停下来。 另有,缓存一致性协议EMSI应可以同步缓存,实际上也没效果。展开共 1 条评论
- 天使梦泪2020-07-07老师好,俩个线程共同执行X共享变量,有种结果是2,1,这个结果是怎么出现的哈?可以帮分析下么?共 1 条评论
- will2020-04-04大概理解了所谓的数据一致性,还需要多复习几遍