Is reordering of instance initialization and assignment to a shared variable possible?

后端 未结 2 643
深忆病人
深忆病人 2021-01-02 02:23

I was reading an essay, which actually talks about double-checked locking, but I\'m surprised about an even more basic failure in the code presented as examples. It is state

2条回答
  •  遥遥无期
    2021-01-02 03:13

    A call to foo = new Foo(); involves several operations which might be reordered unless you introduce proper synchronization to prevent it:

    1. allocate memory for the new object
    2. write the default values of fields (a = 0)
    3. write the initial values of fields (a = 1)
    4. publish the reference to the newly created object

    Without proper synchronization, steps 3 and 4 might be reordered (note that step 2 necessarily happens before step 4), although it is unlikely to happen with hotspot on a x86 architecture.

    To prevent it you have several solutions, for example:

    • make a final
    • synchronize access to foo (with a synchronized init AND getter).

    Without going into the intricacies of JLS #17, you can read JLS #12.4.1 about class initialization (emphasis mine):

    The fact that initialization code is unrestricted allows examples to be constructed where the value of a class variable can be observed when it still has its initial default value, before its initializing expression is evaluated, but such examples are rare in practice. (Such examples can be also constructed for instance variable initialization.) The full power of the Java programming language is available in these initializers; programmers must exercise some care. This power places an extra burden on code generators, but this burden would arise in any case because the Java programming language is concurrent.

提交回复
热议问题