Is this a better version of Double Check Locking without volatile and synchronization overhead

一世执手 提交于 2019-12-01 05:55:45

There is no way to achieve "cheap" double-checked locking in pure JMM; something got to give.

Your solution doesn't work because a volatile write can be reordered with a following normal action. See jsr133 cookbook for allowed reordering in the so called "roach motel" model. "Roach motel" is a stronger model than JMM, so if your solution fails in roach motel, it fails in JMM.

roach motel model
reordering between a normal action and a volatile/monitor action

   --                              <--
  |                                   |
  |    VolatileLoad / MonitorEnter    | forbidden
  |                                   |
   --> allowed                      --


   --> allowed                      --
  |                                   | 
  |    VolatileStore / MonitorExit    | forbidden
  |                                   |
   --                              <--

There is a way to deter reordering of two normal actions in "roach motel" model

(1) action#1
(2) volatile write
(3) volatile read
(4) action#4

(1) cannot be reordered with (2), and (4) cannot be reordered with (3), therefore (1) and (4) cannot be reordered.

However, be warned that "roach motel" model is a stronger model than JMM. You cannot be sure that a JVM conforms to roach motel model. For a concrete example

action#1
synchronized(new Object()){}
synchronized(new Object()){}
action#4

according to roach motel, action#1 and action#4 can't be reordered; however JVM can legitimately (allowed by JMM) remove the two sync block then reorder the remaining two actions.

The JLS (Section 17.4.5) states:

"A write to a volatile field (§8.3.1.4) happens-before every subsequent read of that field."

You are not reading the fence variable after it is updated, so there is no "happens-before" relationship between the thread that updates fence and any second thread. That means that the second thread is not guaranteed to see the updates to the field variable made by the first thread.

In short, your "improved" code is a broken implementation of double-checked locking.

According to sources I trust, it seems to be a working and safe code. Write of a volatile variable must enforce the write of all other variables and can be reordered neither with volatile nor with normal assignments.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!