Java Happens-Before and Thread Safety Java Happens-Before and Thread Safety multithreading multithreading

Java Happens-Before and Thread Safety


So what you are asking is correct assumption. You do not need to make it thread safe if you can guarantee that it is only used this way. You can't pass a half constructed object around in java, so the "Constructor might not be finished" is not possible.

So if you do

new Thread(new Runnable() {    public void run() {          final MyClass instance = new MyClass(10);          new Thread(new Runnable() {               public void run() {                    instance.put("one", "one");                      ....               }           }).start();     }}).start();

You are fine :) This is what you described, created by Thread1 but only used by Thread2. There is no way for the thread to collide with itself.

Thread-Safe is a different definition where the composed entity may safely be interacted with by multiple threads. In the case you described, that scenario does not happen, since you essentially have a thread that constructs and another that manipulates.


This is a bit tricky to answer, because the JLS doesn't contain the concept of a class being thread-safe — all it specifies is relationship between actions (e.g. a write to a field, a read from a field, etc).

That said, by most definitions, this class is not thread-safe -- it contains data races caused by unsynchronized access to a not-thread-safe Map. However, your usage of it is thread-safe, because you safely publish this.map to Thread 2 after construction, and at that point this.map is only ever accessed by one thread, in which case thread safety isn't an issue.

In other words, this is only slightly more involved than asking whether HashMap is thread-safe when created and accessed only within one thread. The answer in that case is that HashMap is not thread safe, but it doesn't need to be.

Similarly, your class isn't thread safe, but it sounds like it may not need to be.


If you stand to your definition of what will happen then it would in fact be thread safe. That is, only thread-2 will put and get from the Map.

Since the Map is declared final, you do establish a happens-before relationship with respect to the write of thread-1 and read of thread-2.

a) Since the reference to the map is declared final, all other threads would see the initial state of the map (happens-before is established).

Yes. An empty HashMap with size specified.

b) Since put/get/printMap/etc are only ever called by Thread2, there is no need for mutual-exclusion.

Yes as well, though this type of logic usually scares me in practice :)