1.java内存模型

2.可见性
2.1 退不出的循环




2.2 解决方案
volatile(易变关键字)
它可以用来修饰成员变量和静态成员变量,它可以避免线程从自己的工作缓存中查找变量的值,必须到主存中获取它的值,线程操作volatile变量都是直接操作主存。
2.3 可见性vs原子性



2.4 模式之两阶段终止
2.5 模式之Balking
3.有序性
3.1 指令重排

3.1.1 鱼罐头的故事


3.1.2 指令重排序优化

3.1.3 支持流水线的处理器


3.2 诡异的结果
3.2.1 问题


这种现象叫做指令重排,是JIT编译器在要运行时的一些与优化,这个现象需要通过大量测试才能复现
3.2.2 验证
借助java并发压测工具 jcstress
https://wiki.openjdk.java.net/display/CodeTools/jcstress
mvn archetype:generate -DinteractiveMode=false -DarchetypeGroupId=org.openjdk.jcstress -DarchetypeArtifactId=jcstress-java-test-archetype -DarchetypeVersion=0.5 -DgroupId=com.shm.demo -DartifactId=ordering -Dversion=1.0
创建maven项目ordering
@JCStressTest
@Outcome(id = {"1","4"}, expect = Expect.ACCEPTABLE, desc = "ok")
@Outcome(id = "0", expect = Expect.ACCEPTABLE_INTERESTING, desc = "!!!!")
@State
public class ConcurrencyTest {
int num = 0;
boolean ready = false;
@Actor
public void actor1(II_Result r) {
// Put the code for first thread here
if(ready){
r.r1=num+num;
}else{
r.r1=1;
}
}
@Actor
public void actor2(II_Result r) {
// Put the code for second thread here
num = 2;
ready = true;
}
}
运行:

结果:

3.2.3 禁用--volatile
volatile boolean ready = false;
3.3 原理之volatile
volatile原理: https://blog.youkuaiyun.com/java_shm/article/details/108759274
3.4.happens-before规则







上面的变量都是指成员变量或静态成员变量
3.5 习题
3.5.1 balking模式习题
希望doInit()方法仅被调用一次,下面的实现是否有问题?为什么?

3.5.2 线程安全单例习题






4.小结

申明:内容来自网络,仅供学习使用
https://www.bilibili.com/video/BV1jE411j7uX
本文深入探讨Java内存模型的核心概念,包括可见性和有序性,并通过实例解释了如何利用volatile关键字确保线程间的可见性及禁止指令重排序。同时,介绍了jcstress工具的使用方法来验证这些特性。
1064

被折叠的 条评论
为什么被折叠?



