线程安全性 - 有序性及总结

线程安全性 - 有序性

线程安全性 - 有序性及总结_第1张图片

有序性 - happens-before原则(先行发生原则)

Java内存模型具有先天的有序性,不通过任何手段,就能得到保证的有序性,称为happens-before原则。如果两个操作的执行顺序无法从本原则推测出来,虚拟机将可随意地对其进行重排序。
Java内存模型中,允许编译器和处理器对指令进行重排序,但是重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性。

1、程序次序规则

一个线程内,按照代码顺序,书写在前面的操作先行发生于书写在后面的操作。
(理解:代码的执行顺序看起来是按照书写顺序执行的,但是虚拟机会对代码指令进行重排序,虽然进行了重排序,但是最后执行的结果是与程序顺序执行的结果一致的,他只会对不存在数据依赖性的代码进行重排序。因此在单个线程中,程序看起来是有序执行的,事实上,这个规则是为了保证程序在单线程中是有序执行的,但无法保证程序在多线程环境中执行的正确性)

2、锁定规则

一个unLock操作先行发生于后面对同一个锁的lock操作
(理解:也就是说不论是在单线程还是多线程,同一个锁如果是锁定状态,那必须先对锁进行unlock释放操作,后面才能进行lock操作)。

线程安全性 - 有序性及总结_第2张图片

3、volatile变量规则

对一个变量的写操作先行发生于后面对这个变量的读操作。
(理解:如果两个线程分别对volatile变量进行读写操作,那么写操作一定先于读操作,参考:https://blog.csdn.net/wangnanwlw/article/details/86467987)

4、传递规则

如果操作A先行发生于操作B,而操作B又先行发生于操作C,则可以得出操作A先行发生于操作C
(理解:提现了happens-before原则具有传递性)
线程安全性 - 有序性及总结_第3张图片

5、线程启动规则

Thread对象的start()方法先行发生于此线程的每一个动作。

6、线程中断规则

对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生。

线程安全性 - 有序性及总结_第4张图片

7、线程终结规则

线程中所有的操作都先行发生于线程的终止检测,我们可以通过Thread.join()方法结束,Thread.isAlive()的返回值手段检测到线程已经终止执行。

8、对象终结规则

一个对象的初始化完成先行发生于他的finalize()方法的开始

这两天规则主要介绍线程的所有操作必须在终结之前完成

线程安全性 - 有序性及总结_第5张图片

happens-before 8个原则介绍完了,如果两个操作的次序无法从happens-before原则推导出来,那么就不能保证他们的有序性,虚拟机就可以随意的对他们进行重排序

线程安全性 - 总结

原子性:提供互斥访问,同一时刻只允许一个线程访问,atomic包,cas算法,synchronize,lock
可见性:指一个线程对主内存的修改,可以及时被其他线程观察到,synchronize,volatile
有序性: happens-before ,一个线程观察其他线程的指令执行顺序,由于指令重排序的结果,这个观察结果都是杂乱无序的,如果两个操作的执行次序无法从happens-before推导出来,那么他们就不能保证有序性,虚拟机可以随意的他们进行重排序

线程安全性 - 有序性及总结_第6张图片

你可能感兴趣的:(java,并发)