-
原子性: 对基本类型的变量读取与赋值是保证原子性的,要么都成功,要么都失败,这些操作不可中断。
i = 10;
cache 10, memory 10a = 10; 原子性
b = a; 不满足;1. read a; 2. assinged b
c++; 不满足;1. read c; 2. add c ; 3.assinged to c
c=c+1; 不满足;1. read c; 2. add c ; 3.assinged to c但long, double也有可能不保证原子性哦,有高低位赋值性情况,这个会在后面的笔记中提到。
-
可见性:使用关键字volatile,来保证可见性,但不会保证原子性,volatile变量修改,会直接作用于主内存当中,其它线程cache中变量会失效,会重新从主存中读取。
-
有序性:happen-before relationship
(1) 代码的执行顺序,一段代码在单线程中执行的结果是有序的。注意是执行结果,因为虚拟机、处理器会对指令进行重排序(重排序后面会详细介绍)。虽然重排序了,但是并不会影响程序的执行结果,所以程序最终执行的结果与顺序执行的结果是一致的。故而这个规则只对单线程有效,在多线程环境下无法保证正确性。(2) unlock必须发生在lock之后,这个规则比较好理解,无论是在单线程环境还是多线程环境,一个锁处于被锁定状态,那么必须先执行unlock操作后面才能进行lock操作。
(3) volatile修饰的变量,对一个变量的写操作先于对该变量的读操作(多线程),这是一条比较重要的规则,它标志着volatile保证了线程可见性。通俗点讲就是如果一个线程先去写一个volatile变量,然后一个线程去读这个变量,那么这个写操作一定是happens-before读操作的。
(4) 传递规则,操作A先于B,B先于C,那么A肯定先于C
(5) 线程的启动规则,start方法肯定先于线程的run
(6) 线程的中断规则,interrupt必须发生在捕获该动作之前(打个比方,Sleep时,interrupt然后才会有异常,而不是有异常了,才会interrupt)
(7) 对象销毁规则,一个对象的初始化必须发生在finalize之前
(8) 线程的终结规则,所有的操作都发生在线程死亡之前
【笔记】高并发编程第二阶段09讲、指令重排序,happens-before规则精讲
最新推荐文章于 2022-01-21 12:37:27 发布