简体   繁体   中英

Java Concurrency - Publishing Immutable Objects (Java Concurrency In Practice)

In Java Concurrency In Practice, the author stated that

  1. Immutable objects can be published through any mechanism
  2. Immutable objects can be used safely by any thread without additional synchronization, even when synchronization is not used to publish them.

Does it mean that the following idioms are safe to publish immutable objects?

public static List<ImmutableObject> list = new ArrayList<ImmutableObject>();

// thread A invokes this method first
public static void methodA () {
    list.add(new ImmutableObject());
}

// thread B invokes this method later
public static ImmutableObject methodB () {
    return list.get(0);
}

Would there be any data race? (which means thread B may not be able to see the Immutable Object in the list added by thread A)

Thank you very much.


More, the author said that the following code is safe if Resource is immutable.

@NotThreadSafe
public class UnsafeLazyInitialization {
    private static Resource resource;

    public static Resource getInstance() {
        if (resource == null)
            resource = new Resource();  // unsafe publication
        return resource;
    }
}

Section16.3 The guarantee of initialization safety allows properly constructed immutable objects to be safely shared across threads without synchronization, regardless of how they are published even if published using a data race. (This means that unsafeLazyInitialization is actually safe if Resource is immutable.)

Yes, you are correct, there is a data race.

Only the ImmutableObject is immutable and can be shared safely between threads, your List , however, does not have these same guarantees, so there is a data race between adding the ImmutableObject and retrieving it.

In JCIP, the authors meant immutable objects are safe to publish in the sense that you don't have to worry about doing things like making defensive copies.

As to:

Immutable objects can be used safely by any thread without additional synchronization, even when synchronization is not used to publish them.

This statement means that given 2 threads with an immutable object A that they both acquired through any means, they can both use object A without worrying about thread-safety issues.

Your List<ImmutableObject> list container object is not immutable. Hence, add and get method on it will not be threadsafe. These methods need to be synchronized for concurrent access from multiple threads.

Your question suggests that you are anticipating section 5.3 - blocking queues and the producer consumer pattern. Here is something similar using a blocking queue:

public class Blocking
{
   private BlockingQueue<ImmutableObject> queue = new ArrayBlockingQueue<ImmutableObject>(10);

   public void methodA() {
      queue.add(new ImmutableObject());
   }

   public ImmutableObject methodB() throws InterruptedException
   {
      return queue.take();
   }
   static class ImmutableObject
   {

   }
}

The blocking queue is highly mutable - but is designed to be thread safe so you can use it without extra synchronization. As long as the objects that you are passing are immutable the entire design is thread safe.

In the example above, methodB uses "take" which will block until methodA is called to put something in the queue. Or until the thread is interrupted at which point it would exit via an InteruptedException

Yes there is definite chance of data race. Here is a situation:

Although Thread A is inside methodA and then Thread B would be executing methodB , there is no guarantee that methodA has returned before methodB . If, unfortunately, methodB has already returned while methodA is yet to return, there would be high chance to get IndexOutOfBoundsException :

// thread A invokes this method first
public static void methodA () {
    //assume control is taking time at this point, while thread B already returned!!!

    list.add(new ImmutableObject());
}

// thread B invokes this method later
public static ImmutableObject methodB () {
    return list.get(0);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM