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