How to make a major mistake with improper publication of the object
First, we need to define an improper publication. If in thread A you create the object X and in the thread B you have a reference to the object X before the constructor of X finishes his work, that is an improper publication. Thread B can work with object X before it is still not constructed properly.
Take a look at this example from Java Concurrency in Practice book.
public class Holder {
private int n;
public Holder(int n) { this.n = n; }
public void assertSanity() {
if (n != n)
throw new AssertionError("This statement is false.");
}
}
Believe it or not, you can receive AssertionError
!
How is AssertionError
possible?
It is important to realize that on the line if (n != n)
reading thread reads the value of the n
twice(because n
appears on both sides of the !=
operator)! A precondition for this problem is that one thread creates the object and another uses that same object:
- Step 1: Thread A starts creating the object by invoking the constructor
- Step 2: Before thread A reaches
this.n = n;
line, thread B reachesif (n != n)
line and readn
for the first time - Step 3: Thread A executes
this.n = n;
line and nown
has a different value - Step 4: Thread B reads the
n
second time(nown
has a different value) And that is how you have theAssertionError
. Of course, as you can see, you need an awful timing for this bug to occur but the bug is present! For the homework, you can try to figure out why it looks like this bug would be rare but in reality the probability that this will happen is very high!
How should we approach this problem?
There are 4 ways(you can find explanations of why those four ways help here):
- Initializing an object reference from a static initializer
- Storing a reference to it into a volatile field or AtomicReference
- Storing a reference to it into a final field of a properly constructed object
- Storing a reference to it into a field properly guarded by a lock.
If you would like to learn more about how to solve this problem, take a look at thisĀ article.
Further reading
The post that you currently read is intended to tickle your curiosity. If this article was interesting to you, here are some great resources on the multithreading topic: