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

血红的双手。 提交于 2019-12-01 01:26:33

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