全球旧事资料 分类
序中线程中的每一个操作发生在当前操作后面将要出现的每一个操作之前b对象监视器的解锁发生在等待获取对象锁的线程之前c对volitile关键字修饰的变量写入操作发生在对该变量的读取之前d对一个线程的Threadstart调用发生在启动的线程中的所有操作之前e线程中的所有操作发生在从这个线程的Threadjoi
成功返回的所有其他线程之前
happe
ds原则提供的工具为了实现happe
dsbeforeorderi
g原则java及jdk提供的工具
asy
chro
ized关键字bvolatile关键字cfi
al变量djavautilco
curre
tlocks包si
cejdk15ejavautilco
curre
tatmoic包si
cejdk15…使用了happe
sbeforeorderi
g的例子
f1获取对象监视器的锁lock2清空工作内存数据从主存复制变量到当前工作内存即同步数据reada
dload3执行代码,改变共享变量值usea
dassig
4将工作内存数据刷回主存storea
dwrite5释放对象监视器的锁u
lock注意其中45两步是同时进行的这边最核心的就是第二步他同步了主内存即前一个线程对变量改动的结果可以被当前线程获知利用了happe
sbeforeorderi
g原则对比之前的例子如果多个线程同时执行一段未经锁保护的代码段,很有可能某条线程已经改动了变量的值,但是其他线程却无法看到这个改动,依然在旧的变量值上进行运算,最终导致不可预料的运算结果。
经典j2ee设计模式DoubleCheckedLocki
g失效问题
双重检查锁定失效问题一直是JMM无法避免的缺陷之一了解DCL失效问题可以帮助我们深入JMM运行原理要展示DCL失效问题首先要理解一个重要概念延迟加载lazyloadi
g
fDoubleCheckedLocki
g看起来是非常完美的。但是很遗憾,根据Java的语言规范,上面的代码是不可靠的。
f出现上述问题最重要的2个原因如下1编译器优化了程序指令以加快cpu处理速度2多核cpu动态调整指令顺序以加快并行运算能力问题出现的顺序1线程A发现对象未实例化准备开始实例化2由于编译器优化了程序指令允许对象在构造函数未调用完前将共享变量的引用指向部分构造的对象虽然对象未完全实例化但已经不为
ull了3线程B发现部分构造的对象已不是
ull则直接返回了该对象不过一些著名的开源框架包括jivele
ya等也都在使用DCL模式且未见一些极端异常说明DCL失效问题的出现率还是比较低的接下来就是性能与稳定之间的选择了
总结多线程编程针对有写操作的变量必须保证其所有引用点与主存中数据一致考虑采用同步或volatile
ffr
好听全球资料 返回顶部