Why are safe objects safe when double checking for locks?

The bottom of http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html says:

Double check lock immutable objects

If Helper is an immutable object, so that all Helper fields are final, then a double lock check will work without the need for mutable fields. The idea is that a reference to an immutable object (such as String or Integer) should behave just like an int or float; reading and writing references to immutable objects are atomic.

Sample and explanation of volatile:

// Broken multithreaded version // "Double-Checked Locking" idiom class Foo { private Helper helper = null; public Helper getHelper() { if (helper == null) synchronized(this) { if (helper == null) helper = new Helper(); } return helper; } // other functions and members... } 

The first reason it does not work

The most obvious reason why it does not work is that the entries that initialize the Helper object and the entry in the helper field can be executed or perceived out of order. Thus, the thread that calls getHelper () could see a non-zero reference to the auxiliary object, but see the default values ​​for the fields of the auxiliary object, and not the values ​​set in the constructor.

If the compiler makes a call to the constructor, then the records that initialize the object and the entry in the helper field can be freely reordered if the compiler can prove that the constructor cannot throw an exception or synchronize.

Even if the compiler does not reorder these records, on the multiprocessor, the processor or memory system can change the order of the recording, as perceived by the thread executing on another processor.

My question is: why doesn't an immutable class have a problem? I do not see any relation to reordering with class change.

thanks

+6
source share
2 answers

The reason code breaks for regular objects is because helper may not be null, but point to an object that has not yet been fully initialized, as described in your quote.

However, if the Helper class is immutable, which means that all its fields are final, the Java memory model ensures that they are safely published, even if the object is accessible through a data race (which is the case in your example):

Fields

final also allows programmers to implement thread-safe immutable objects without synchronization. A thread-safe immutable object is considered immutable for all threads, even if the data race is used to pass references to an immutable object between threads . This can provide security guarantees against misuse of an immutable class with incorrect or malicious code. The final fields must be used correctly to guarantee a guarantee of immutability.

+1
source

Immutable classes have a problem. The part you specified is correct after the changes in the Java memory in JSR133.

In particular, changes that affect immutable objects are associated with some changes made to the final key. Checkout http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#finalRight .

Main part:

Values ​​for the final fields of the object are set in its constructor. Assuming that the object is built “correctly”, after creating the object, the values ​​assigned to the final fields in the constructor will be visible to all other threads without synchronization.

0
source

Source: https://habr.com/ru/post/977361/


All Articles