系列文章目录
第一章 java JUC并发编程 Future: link
第二章 java JUC并发编程 多线程锁: link
第三章 java JUC并发编程 中断机制: link
第四章 java JUC并发编程 java内存模型JMM: link
第五章 java JUC并发编程 volatile与JMM: link
第六章 java JUC并发编程 CAS: link
第七章 java JUC并发编程 原子操作类增强: link
第八章 java JUC并发编程 ThreadLocal: link
第九章 java JUC并发编程 对象内存布局与对象头: link
第十章 java JUC并发编程 Synchronized与锁升级: link
第十一章 java JUC并发编程 AbstractQueuedSynchronizer之AQS: link
文章目录
1 前言
1.1 计算机硬件存储体系
1.2 硬件体系与JMM的关系
1.3 java内存模型java Memory Model
2 JMM规范下三大特性
2.1 可见性
如果没有原子性会产生脏读
2.2 原子性
指一个操作时不可打断的,即多线程环境下,操作不能被其他线程干扰
2.3 有序性
2.4 JMM规范下,多线程对变量的读写过程
定义的所有共享变量都存储在物理内存中
每个线程都有自己独立的工作内存,里面保存该线程使用到的变量的副本(主内存中改变量的一份拷贝)
线程对共享变量所有的操作都必须先在线程自己的工作内存中进行后写回主内存,不能直接从内存中读写(不能越级)
不通线程之间也无法直接访问其他线程的工作内存中的变量,线程间变量值得传递需要通过内存来进行(同级不能互相访问)
2.5 JMM规范下,多线程现行发生原则happens-before
在JMM中如果一个操作执行的结果需要对另一个操作可见性或者代码重排序,那么这两个操作之间必须存在happens-before(先行发生)原则。逻辑上的先后关系
2.5.1 x、y案例说明
先行发生原则说明
2.5.2 happens-before总原则
如果一个操作happens-before另一个操作,那么第一个操作的执行结果将对第二个操作可见,而且第一个操作的执行顺序排在第二个操作之前。
两个操作之间存在happens-before关系,并不意味着一定要按照happens-before原则指定的顺序来执行
如果重排序之后的执行结果与按照happens-before关系来执行的结果一致,那么这种重排序并不非法
2.5.3 happens-before之8条
2.5.3.1 次序规则
一个线程内,按照代码顺序,写在前面的操作先行发生于写在后面的操作
前一个操作的结果可以被后续的操作获取
前一个操作把变量X赋值为1,那么后面一个操作肯定能知道x已经变成1
2.5.3.2 锁定规则
一个unLock操作先行发生于后面(这里的后面指的是时间上的先后)对同一个锁的lock操作
对于同一把锁objectLock,threadA一定先unlock同一把锁后B才能获得该锁,A先行发生于B
2.5.3.3 valatile变量规则
对一个volatile变量的写操作先行发生于后面这个变量的读操作,
前面的写对后面的读是可见的,这里的后面同样是指时间上的先后
2.5.3.4 传递规则
如果操作A先行发生于操作B,而操作B又先行发生于操作C,则可以的除操作A先行发生于操作C
2.5.3.5 线程启动规则(Thread Start Rule)
Thread对象的start()方法先行发生于此线程的每一个动作
2.5.3.6 线程中断规则(Thread Interruption Rule)
对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生
可以通过Thread.interrupted()检测到是否发生中断
也就是说你先调用interrupt()方法设置过中断标志位,我才能检测到中断发送
2.5.3.7 线程终止规则(Thread Termination Rule)
线程中的所有操作都先行与对此线程的终止检测,我们可以通过isAlive()等手段检测线程是否已经终止执行
2.5.3.8 对象终结规则(Finalizer Rule)
一个对象的初始化完成(构造函数执行结束)先行发生于它的finalize()方法的开始
finalize:JVM虚拟机里java对象要被回收的时候最终执行下这个方法