并发与高并发(十)-线程安全性-有序性与总结
前言
本章将讲解一下线程安全性中的有序性,并对之前的线程安全性部分作一个简单的总结。
主体内容
一、首先,给出有序性的相关知识。
1.有序性:Java内存模型中,允许编译器和处理器对指令进行重排序,但是重排序过程中不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性。
2.有序性遵从happens-before原则,happens-before原则包含八大原则:
(1) 程序次序原则:一个线程中,代码按照顺序,书写在前面的操作先行书写在后面的操作。(程序看起来是按照代码的顺序执行的,但是虚拟机优化可能会对代码进行执行重排序,那也就是说两者共同走到最后的结果是相同的)
(2) 锁定规则:一个unLock操作先行发生于后面一个Lock操作。
(3) volatile变量规则,对一个变量的写操作先行发生于对这个变量的读操作。
(4)传递性规则,在程序中,如果存在A大于B,并且B大于C,那么A的结果必然大于C。
(5)线程启动规则:每一个线程的Thread独享的start()方法先行发生于线程中的每一个动作。
(6)线程中断规则:对线程的interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生。
(7)线程终结规则:线程中所有的操作都先行发生于线程的终止检测,我们可以通过Thread.join()方法结束,Thread.isAlive()的返回值手段检测到线程已经终止执行。
(8) 对象的终结规则:一个对象的初始化先行发生于他的finalize()方法的开始。
以上原则中,如果两个线程在执行过程中不能从happens-before原则中推倒出来,那么java虚拟机就会对其进行指令重排序,就不能保证线程的有序性了。
最后,我们对线程安全性作一个系统的总结:
原子性:synchronized ,Lock,Atomic包、CAS算法。
可见性:synchronized,volatile关键字。
有序性:happens-before原则。