Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why is Immutable Objects safe in Double-Checked Locking?

At the about bottom of http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html, it says:

Double-Checked Locking Immutable Objects

If Helper is an immutable object, such that all of the fields of Helper are final, then double-checked locking will work without having to use volatile fields. The idea is that a reference to an immutable object (such as a String or an Integer) should behave in much the same way as an int or float; reading and writing references to immutable objects are atomic.

The sample and explanation of mutable one is as follows:

// 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 doesn't work

The most obvious reason it doesn't work it that the writes that initialize the Helper object and the write to the helper field can be done or perceived out of order. Thus, a thread which invokes getHelper() could see a non-null reference to a helper object, but see the default values for fields of the helper object, rather than the values set in the constructor.

If the compiler inlines the call to the constructor, then the writes that initialize the object and the write to the helper field can be freely reordered if the compiler can prove that the constructor cannot throw an exception or perform synchronization.

Even if the compiler does not reorder those writes, on a multiprocessor the processor or the memory system may reorder those writes, as perceived by a thread running on another processor.

My question is: why immutable class does't have the problem? I cannot see any relation of the reorder with whether the class is mutable.

Thanks

like image 457
Fang Zhen Avatar asked Oct 28 '14 15:10

Fang Zhen


People also ask

Why are immutable objects thread-safe?

To put it simply, a class instance is immutable when its internal state can't be modified after it has been constructed. A MessageService object is effectively immutable since its state can't change after its construction. So, it's thread-safe.

Is double-checked locking safe?

Double-checked locking is a common pattern for lazy initialization of a field accessed by multiple threads.

What is the main advantage of immutable objects?

Immutable objects offer a number of advantages for building reliable applications. As we don't need to write defensive or protective code to keep application state consistent, our code can be simpler, more concise, and less error-prone than when we define mutable objects.

What are the benefits of an immutable object when we are dealing with concurrency?

Immutable objects are particularly useful in concurrent applications. Since they cannot change state, they cannot be corrupted by thread interference or observed in an inconsistent state.


1 Answers

The reason why the code is "broken" for usual objects is that helper could be non null but point to an object that has not been completely initialised yet as explained in your quote.

However if the Helper class is immutable, meaning that all its fields are final, the Java Memory Model guarantees that they are safely published even if the object is made available through a data race (which is the case in your example):

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

like image 116
assylias Avatar answered Oct 15 '22 02:10

assylias