Mutithreading with System.out.format and System.out.println
deadlock, java, multithreading, println
Solution
There is no difference in whether you use `System.out.print` or `System.out.format`: they're basically doing the same thing.
The deadlock occurs here if execution of `Gaston.bow(Alphonse)` is started between the start of `Alphonse.bow(Gaston)` and `bower.bowBack(Alphonse)` (or vice versa): the two threads are waiting for a monitor held by the other, and thus deadlock occurs.
This happens inconsistently, because it depends upon a subtle timing issue, depending upon how the threads are scheduled - it is possible that `Alphonse.bow` and `bower.backBack(Alphonse)` complete before `Gaston.bow` is executed, so it looks like there is no deadlock.
The classic way to fix this is to order the lock acquisition, so that the first the same lock is acquired first every time; this prevents the possibility of deadlock:
public void bow(Friend bower) { // Method no longer synchronized.
int firstHash = System.identityHashCode(this);
int secondHash = System.identityHashCode(bower);
Object firstMonitor = firstHash < secondHash ? this : bower;
Object secondMonitor = firstHash < secondHash ? bower : this;
synchronized (firstMonitor) {
synchronized (secondMonitor) {
// Code free (*) of deadlocks, with respect to this and bower at least.
}
}
}
(*) It's not quite guaranteed to be deadlock free, since `System.identityHashCode` can return the same value for distinct objects; but that's reasonably unlikely.
It's an application of the Birthday paradox: if you've got just two monitors, the chance of collision is something like 10^-18; but if you've got >77k monitors, a collision is more likely than not.
Problem
I came across this example on Oracle's Java Tutorial describing Deadlock in multi threading scenarios. So in this example I made following change at line 17 and line 18. ``` public class DeadLock { static class Friend { private final String name; public Friend(String name) { this.name = name; } public String getName() { return this.name; } public synchronized void bow(Friend bower) { //My Changes //System.out.format("%s: %s" + " has bowed to me!%n", this.name, bower.getName()); //Line 17 System.out.println(this.name + ": " + bower.getName() + " has bowed to me!"); //Line 18 bower.bowBack(this); } public synchronized void bowBack(Friend bower) { System.out.format("%s: %s" + " has bowed back to me!%n", this.name, bower.getName()); } } public static void main(String[] args) { final Friend alphonse = new Friend("Alphonse"); final Friend gaston = new Friend("Gaston"); new Thread(new Runnable() { @Override public void run() { alphonse.bow(gaston); } }).start(); new Thread(new Runnable() { @Override public void run() { gaston.bow(alphonse); } }).start(); } } ``` Upon doing these changes the program terminated successfully without causing deadlock and printed following output ``` Alphonse: Gaston has bowed to me! Gaston: Alphonse has bowed back to me! Gaston: Alphonse has bowed to me! Alphonse: Gaston has bowed back to me! ``` So my question is- why did it behave like this? How did the println statement prevent the deadlock?