One of the SCJP practice exam questions I ran across supplied the code in the SafeDeposit class. The answer to the question claimed that if another class used multiple threads that it would be possible for the unsynchronized (non thread safe) getInstance() method to return multiple instances of SafeDeposit. I have tried, and tried and cannot get the toString() method to indicate that there is ever more than one SafeDeposit instance created. Am I missing something, or is this just one of those things that "could" happen but is really, really, really unlikely to happen?
class SafeDeposit {
private static SafeDeposit sd;
public static SafeDeposit getInstance() {
if(sd == null) sd = new SafeDeposit();
return sd;
}
private SafeDeposit() { }
}
public class PrivCon {
public static void main(String[] args) {
String checker;
SafeThief wizard = new SafeThief();
SafeThief wizard2 = new SafeThief();
for(int i = 0; i < 10; i ++) {
new Thread(wizard).start();
new Thread(wizard2).start();
}
}
}
class SafeThief implements Runnable {
public void run() {
System.out.println(SafeDeposit.getInstance().toString());
}
}
Try this code and see how unlikely it really is:
This is my typical output:
Hardly any duplicates at all.
If you want to know why, it's because I added warmup code, which caused the
getInstance()
method to be JIT-compiled into an aggressively optimized piece of code which leverages the liberties given by the Java Memory Model.I also added some
sleep
time to the beginning of theRunnable
because as soon as one thread writes the value, those threads which start after that point will reliably observe the write. So it is better to first let all threads start, then let them callgetInstance
.