一.JMM
在不同硬件和操作系统下保证线程安全,引出JMM Java内存模型,屏蔽操作系统和硬件的差异,使得一套代码在不同平台都能达到线程安全的条件。
JMM规定所有变量必须存储在主内存中,每个线程还有自己的工作内存,工作内存保存了这个线程用到的变量的主内存的拷贝,线程对变量的操作必须在工作内存中进行,而不能直接读取主内存。
不同线程之间不能访问对方工作内存的变量,线程间变量的传递必须依靠主内存和工作内存的数据同步进行。JMM内存模型类似于CPU高速缓存和内存的关系。
二.HB原则(happens before)
happens before 第一个线程的操作结果对第二个可见且必须在第二个线程执行之前执行
程序顺序规则
:as if serial 单线程是,不管指令怎么重排序,单线程的程序执行结果不会改变
①.对于有依赖关系的操作不能重排序,因为会改变程序运行的结果
②.对于没有依赖关系的指令,不管怎么重排序,也不会改变程序运行的结果
传递性规则
A HB B B HB C -> A HB C
三.volatile规则
volatile底层通过内存屏障,防止了指令重排序,这个昨天的可见
四.监视器锁规则
int x=10;
synchronized (this) { // 此处自动加锁
// x 是共享变量, 初始值 =10
if (this.x < 12) {
this.x = 12;
}
} // 此处自动解锁
线程二可见线程一对x的修改操作
五.start规则
A调用threadb.start(),A的threadb.start()之前的操作HB B的任何操作
A执行B.join B的任何操作HB A执行B.join的返回
DCL问题
分配内存地址,初始化,指向地址,重排序可能造成不完整对象
六.Lock
设计锁
1.抢占,设置全局变量,0,1
2.抢占了不处理
3.没有抢占到锁
①等待(wait/notify无法唤醒指定线程)
LockSupport.park/unpark(阻塞、唤醒指定线程)
②排队
双向链表的队列阻塞排队