赞
踩
读《深入理解Java虚拟机》第三版,周志明著。
读《Java并发编程的艺术》方腾飞、魏鹏、程晓明著。
读《Java并发编程实战》。
笔记。
先行发生原则可以判断数据是否存在竞争,线程是否安全。
如果两个操作之间缺乏 happens-before关系,那么 JVM 可以对它们任意地排序。
先行发生是 Java 内存模型中定义的两项操作之间的偏序关系,比如说操作 A
先行发生于操作 B
,其实就是说在发生操作 B
之前,操作 A
产生的影响能被操作 B
观察到,“ 影响 ” 包括修改了内存中共享变量的值、发送了消息、调用了方法等。
《JSR-133: Java Memory Model and Thread Specification》对 happens-before 关系的定义如下:
第一条是JMM对程序的承诺。从程序员的角度来说,可以这样理解 happens-before 关系:如果 A happens-before B,那么Java内存模型将向程序员保证——A操作的结果将对B可见,且A的执行顺序排在B之前。注意这只是Java内存模型向程序员做出的保证!
第二条是JMM对编译器和处理器重排序的约束原则。正如前面所言,JMM其实是在遵循一个基本原则:只要不改变程序的执行结果(指的是单线程程序和正确同步的多线程程序),编译器和处理器怎么优化都行。JMM这么做的原因是:程序员对于这两个操作是否真的被重排序并不关心,程序员关心的是程序执行时的语义不能被改变(即执行结果不能被改变)。
这些先行发生关系无须任何同步器协助就已经存在,可以在编码中直接使用。
控制流顺序
,书写在签名的操作先行发生于书写在后面的操作。注意,这里说的是控制流顺序
而不是程序代码顺序
,因为要考虑分支、循环等结构。unlock 操作
先行发生于后面对同一个锁的 lock 操作
。这里的 “ 后面 ” 是指时间上的先后。volatile 变量
的写操作
先行发生于后面对这个变量的读操作
,这里的 “ 后面 ” 同样是指时间上的先后。start() 方法
先行发生于此线程的每个动作。终止检测
,我们可以通过 Thread::join() 方法是否结束
、Thread::isAlive() 的放回值
等手段检测线程是否已经终止执行。interrupt() 方法
的调用先行发生于被中断线程的代码检测到中断事件的发生,可以通过 Thread::interrupted() 方法
检测到是否有中断发生。finalize() 方法
的开始。操作 A
发行发生于操作 B
,操作 B
先行发生于操作 C
,那就可以得出操作 A
先行发生于操作 C
的结论。Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。