This is the last refactoring example of deadlocked Java code using the “synchronized” keyword.
This example is from a site called Rose India.
I was not able to really use Lombok for this example. The classes that deadlocked extended Thread, and the only method in those classes was the run() method. I did not know if annotating run() with the Lombok annotation would work. The method run() was not marked with the “synchronized” method in the original. Instead there were two synchronized blocks in the run() method. The two classes were using the same String objects to lock, which is why there was a deadlock.
So I decided to do by hand what Lombok does behind the screens. I created a private final object in each method and used those for one of the locks. Just as in the other examples, the deadlock was broken.
Here is the original;
package fromroseindia; // from http://www.roseindia.net/javatutorials/deadlocksinjava.shtml public class DeadLockDemo extends Thread { public static String str1 = "str1"; public static String str2 = "str2"; public static void main( String[] a ) { Thread myThread = new MyThread(); Thread yourThread = new YourThread(); myThread.start(); yourThread.start(); System.out.println( "At the end of main" ); } // end method main private static class MyThread extends Thread { public void run() { synchronized ( str1 ) { System.out.println( "MyThread Holds lock on object str1" ); try { Thread.sleep( 10 ); } catch ( InterruptedException e ) { e.printStackTrace(); } System.out.println( "MyThread waiting for lock on object str2" ); synchronized ( str2 ) { System.out.println( "MyThread Holds lock on objects str1, str2" ); } } System.out.println( "At the end of MyThread.run" ); } // end method run } // end class MyThread private static class YourThread extends Thread { public void run() { synchronized ( str2 ) { System.out.println( "YourThread Holds lock on object str2" ); try { Thread.sleep( 10 ); } catch ( InterruptedException e ) { e.printStackTrace(); } System.out.println( "YourThread waiting for lock on object str1" ); synchronized ( str1 ) { System.out.println( "YourThread Holds lock on objects str1, str2" ); } } System.out.println( "At the end of YourThread.run" ); } // end method run } // end class YourThread } // end class DeadLockDemo
Here is the output of the original:
MyThread Holds lock on object str1 YourThread Holds lock on object str2 At the end of main MyThread waiting for lock on object str2 YourThread waiting for lock on object str1
Here is the refactored version:
package fromroseindia; // refactored version of http://www.roseindia.net/javatutorials/deadlocksinjava.shtml import java.util.UUID; import lombok.Synchronized; public class DeadLockDemoLombok { public static String str1 = "str1"; public static String str2 = "str2"; public static void main( String[] a ) { Thread myThread = new MyThreadLombok(); Thread yourThread = new YourThreadLombok(); myThread.start(); yourThread.start(); System.out.println( "At the end of main" ); } // end method main private static class MyThreadLombok extends Thread { private final Object object1 = new Object(); public void run() { synchronized ( object1 ) { System.out.println( "MyThread Holds lock on object object1" ); try { Thread.sleep( 10 ); } catch ( InterruptedException e ) { e.printStackTrace(); } System.out.println( "MyThread waiting for lock on object str2" ); synchronized ( str2 ) { System.out.println( "MyThread Holds lock on objects object1, str2" ); } } // synchronized ( object1 ) System.out.println( "At the end of MyThreadLombok.run" ); } // end method run } // end class MyThread private static class YourThreadLombok extends Thread { private final Object object2 = new Object(); public void run() { synchronized ( object2 ) { System.out.println( "YourThread Holds lock on object object2" ); try { Thread.sleep( 10 ); } catch ( InterruptedException e ) { e.printStackTrace(); } System.out.println( "YourThread waiting for lock on object str1" ); synchronized ( str1 ) { System.out.println( "YourThread Holds lock on objects str1, object2" ); } } // synchronized ( object2 ) System.out.println( "At the end of YourThreadLombok.run" ); } // end method run } // end class YourThread } // end class DeadLockDemoLombok
Here is the output of the refactored version:
At the end of main YourThread Holds lock on object object2 MyThread Holds lock on object object1 YourThread waiting for lock on object str1 YourThread Holds lock on objects str1, object2 At the end of YourThreadLombok.run MyThread waiting for lock on object str2 MyThread Holds lock on objects object1, str2 At the end of MyThreadLombok.run
Image from Wikipedia page for the Indonesian province of Central Java, assumed allowed under Fair Use.