Last Lombok Refactoring

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.

There are 670 words in this article.