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.

Third Lombok Synchronized Example

Here is another installment of my exploration into concurrency in Java. I have written about finding the Lombok library which uses annotations to reduce boilerplate in Java code.

One of the annotations provided by Lombok is @Synchronized. It is to replace the “synchronized” keyword and prevent some of the problems that can come with using the “synchronized” keyword. There are other annotations available via Lombok, but I have not looked at them.

Here is the third example of a program with a deadlock using the “synchronized” keyword that I refactored with Lombok. I got this example from the Java 2S site.

For this one I have also included the output of each of the programs.

Here is the program:

package newpackage2;

// from http://www.java2s.com/Code/Java/Threads/Threaddeadlock.htm

public class Deadlock extends Object {
    private String objID;

    public Deadlock( String id ) {
        objID = id;
    }

    public synchronized void checkOther( Deadlock other ) {
        print( "entering checkOther()" );

        try {
          Thread.sleep( 2000 );
        } catch ( InterruptedException x ) {
            x.printStackTrace();
        }

        print( "invoke 'other.action()'" );
        other.action();

        print( "leaving checkOther()" );
    }

    public synchronized void action() {
        print( "entering action()" );

        // simulate some work here
        try {
            Thread.sleep( 500 );
        } catch ( InterruptedException x ) {
            x.printStackTrace();
        }

        print( "leaving action()" );
    }

    public void print( String msg ) {
        threadPrint( "objID=" + objID + " - " + msg );
    }

    public static void threadPrint( String msg ) {
        String threadName = Thread.currentThread().getName();
        System.out.println( threadName + ": " + msg );
    }

    public static void main( String[] args ) {
        System.out.println( "Starting Deadlock" );
        final Deadlock obj1 = new Deadlock( "Thread 1" );
        final Deadlock obj2 = new Deadlock( "Thread 2" );

        Runnable runA = new Runnable() {
            public void run() {
                obj1.checkOther( obj2 );
            }
        };

        Thread thread = new Thread( runA, "A" );
        thread.start();

        try {
            Thread.sleep( 200 );
        } catch ( InterruptedException x ) {
            x.printStackTrace();
        }

        Runnable runB = new Runnable() {
            public void run() {
                obj2.checkOther( obj1 );
            }
        };

        Thread threadB = new Thread( runB, "B" );
        threadB.start();

        try {
            Thread.sleep( 5000 );
        } catch ( InterruptedException x ) {
            x.printStackTrace();
        }

        threadPrint( "finished sleeping" );

        threadPrint( "about to interrupt() threadA" );
        thread.interrupt();

        try {
            Thread.sleep( 1000 );
        } catch ( InterruptedException x ) {
            x.printStackTrace();
        }

        threadPrint( "about to interrupt() threadB" );
        threadB.interrupt();

        try {
            Thread.sleep( 1000 );
        } catch ( InterruptedException x ) {
            x.printStackTrace();
        }

        threadPrint( "did that break the deadlock?" );
        System.out.println( "Ending method main" );
    } // end method main
} // end class

Here is its output:

Starting Deadlock
A: objID=Thread 1 - entering checkOther()
B: objID=Thread 2 - entering checkOther()
A: objID=Thread 1 - invoke 'other.action()'
B: objID=Thread 2 - invoke 'other.action()'
main: finished sleeping
main: about to interrupt() threadA
main: about to interrupt() threadB
main: did that break the deadlock?
Ending method main

There is a line that says “Ending method main”, but it does not end unless you kill the program.

Here is the program refactored with Lombok:

package newpackage2;

// example from http://www.java2s.com/Code/Java/Threads/Threaddeadlock.htm
// refactored to use Lombok

import java.util.UUID;
import lombok.Synchronized;

public class DeadlockLombok  extends Object {

    private String objID;
    private final Object someObject = new Object();

    public DeadlockLombok( String id ) {
        objID = id;
    }

    // public synchronized void checkOther(DeadlockLombok other) {
    @Synchronized public void checkOther( DeadlockLombok other ) {
        print( "entering checkOther()" );

        try {
          Thread.sleep( 2000 );
        } catch ( InterruptedException x ) {
            x.printStackTrace();
        }

        print( "invoke 'other.action()'" );
        other.action();

        print( "leaving checkOther()" );
    }

    // @Synchronized public void action() { // does not work
    @Synchronized( "someObject" ) public void action() { // works
    // public synchronized void action() {
        print( "entering action()" );

        // simulate some work here
        try {
            Thread.sleep( 500 );
        } catch ( InterruptedException x ) {
            x.printStackTrace();
        }

        print( "leaving action()" );
    }

    public void print( String msg ) {
        threadPrint( "objID=" + objID + " - " + msg );
    }

    public static void threadPrint( String msg ) {
        String threadName = Thread.currentThread().getName();
        System.out.println( threadName + ": " + msg );
    }

    public static void main( String[] args ) {
        System.out.println( "Starting DeadlockLombok" );
        final DeadlockLombok obj1 = new DeadlockLombok( "Thread 1" );
        final DeadlockLombok obj2 = new DeadlockLombok( "Thread 2" );

        Runnable runA = new Runnable() {
            public void run() {
                obj1.checkOther( obj2 );
            }
        };

        Thread thread = new Thread( runA, "A" );
        thread.start();

        try {
            Thread.sleep( 200 );
        } catch ( InterruptedException x ) {
            x.printStackTrace();
        }

        Runnable runB = new Runnable() {
            public void run() {
                obj2.checkOther( obj1 );
            }
        };

        Thread threadB = new Thread( runB, "B" );
        threadB.start();

        try {
            Thread.sleep( 5000 );
        } catch ( InterruptedException x ) {
            x.printStackTrace();
        }

        threadPrint( "finished sleeping" );

        threadPrint( "about to interrupt() threadA" );
        thread.interrupt();

        try {
            Thread.sleep( 1000 );
        } catch ( InterruptedException x ) {
            x.printStackTrace();
        }

        threadPrint( "about to interrupt() threadB" );
        threadB.interrupt();

        try {
            Thread.sleep( 1000 );
        } catch ( InterruptedException x ) {
            x.printStackTrace();
        }

        threadPrint( "did that break the deadlock?" );
        System.out.println( "End method main" );
    } // end method main

} // end class

Here is the output of the refactored program:

Starting DeadlockLombok
A: objID=Thread 1 - entering checkOther()
B: objID=Thread 2 - entering checkOther()
A: objID=Thread 1 - invoke 'other.action()'
A: objID=Thread 2 - entering action()
B: objID=Thread 2 - invoke 'other.action()'
B: objID=Thread 1 - entering action()
A: objID=Thread 2 - leaving action()
A: objID=Thread 1 - leaving checkOther()
B: objID=Thread 1 - leaving action()
B: objID=Thread 2 - leaving checkOther()
main: finished sleeping
main: about to interrupt() threadA
main: about to interrupt() threadB
main: did that break the deadlock?
End method main

Image from the Wikipedia page for the Indonesian province of West Java, assumed allowed under Fair Use.

Second Lombok Synchronized Example

Here is the second example of a program that deadlocks, with an example that I refactored using the @Synchronized annotation from Project Lombok.

This example was posted on one of the LinkedIn groups in which I first started asking about concurrency using the synchronized keyword. The basic idea to prevent deadlock is to mark the methods with the @Synchronized annotation. For one of them you should create a private, final object, and use the name of that object as the element for that annotation. For the other method that deadlocks I just use the annotation without an element.

Here is the original that was posted:

package fromlinkedin;

// posted on a LinkedIn group discussion

import java.util.UUID;


class A {

    private String uuid = UUID.randomUUID().toString();
    
    synchronized void doA() {
        System.out.println( "In doA for " + uuid );
    }
    
    synchronized void doB( A another ) {
        doA();
        another.doA();
    }

    public static void main( String[] args ) {
        System.out.println( "starting main" );
        final A a1 = new A();
        final A a2 = new A();
        Thread second = new Thread() {
            public void run() {
                a1.doB( a2 );
            }
        };
        second.start();
        a2.doB( a1 );
        System.out.println( "At end of main" );
    } // end method main
} // end class

Here is the version with the Lombok refactoring:

package fromlinkedin;

// Lombok-ed version of a class posted in a LinkedIn group discussion

import java.util.UUID;
import lombok.Synchronized;

class LombokA {
    private final Object objID2 = new Object();
    private String uuid = UUID.randomUUID().toString();
    
    // synchronized void doA(){
    @Synchronized void doA() {
        System.out.println( "In doA for " + uuid );
    }
    
    // synchronized void doB( LombokA another ) {
    @Synchronized( "objID2" ) void doB( LombokA another ) {
        System.out.println( "objID2.hashCode(): " + objID2.hashCode() );
        doA();
        another.doA();
    }

    public static void main( String[] args ) {
        System.out.println( "starting main" );
        final LombokA a1 = new LombokA();
        final LombokA a2 = new LombokA();
        Thread second = new Thread(){
            public void run() {
                a1.doB( a2 );
            }
        };
        second.start();
        a2.doB( a1 );
        System.out.println( "At end of main" );
    } // end method main
} // end class


I have a couple more examples before I get to my notes from No Fluff Just Stuff.

 

Image from the Wikipedia page for the Indonesian province of West Java, assumed allowed under Fair Use.

 

 

First Lombok Synchronized Example

I found some examples of Java programs that become deadlocked due to their incorrect use of the “synchronized” keyword. I decided to try to get them to work using the @Synchronized annotation provided by Project Lombok.

First, here is the example from the Really Big Tutorial.

package really.big.tutorial;

// from Really Big Tutorial:
// http://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html

/**
 *
 * @author ericm
 */
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 ) {
            System.out.format("%s: %s has bowed to me!%n",
                this.name, bower.getName() );
            bower.bowBack( this );
        }
        public synchronized void bowBack( Friend bower ) {
            System.out.format("%s: %s has bowed back to me!%n",
                this.name, bower.getName() );
        }
    } // end class Friend

    public static void main( String[] args ) {
        final Friend alphonse = new Friend( "Alphonse" );
        final Friend gaston = new Friend( "Gaston" );
        new Thread( new Runnable() {
            public void run() { alphonse.bow( gaston ); }
        }).start();
        new Thread( new Runnable() {
            public void run() { gaston.bow( alphonse ); }
        }).start();
        System.out.println( "At the end of main" );
    } // end method main

} // end class Deadlock

 

Here is the same program with Lombok:

package really.big.tutorial;

// Lombok-ed refactoring of deadlock example from Really Big Tutorial:
// http://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html

import java.util.UUID;
import lombok.Synchronized;

public class DeadlockLombok {

    static class Friend {
        private final Object readLock  = new Object[ 0 ];
        private final Object readLock2 = new Object[ 0 ];
        private final String name;
        public Friend( String name ) {
            this.name = name;
        }
        public String getName() {
            return this.name;
        }

        @Synchronized( "readLock" ) public  void bow( Friend bower ) {
            System.out.format( "%s: %s has bowed to me!%n",
                    this.name, bower.getName() );
            bower.bowBack( this );
        }

        // either one works
        // @Synchronized( "readLock2" ) public void bowBack( Friend bower ) {
        @Synchronized public void bowBack( Friend bower ) {
            System.out.format("%s: %s has bowed back to me!%n",
                    this.name, bower.getName() );
        }
    } // end class Friend

    public static void main( String[] args ) {
        final Friend alphonse = new Friend( "Alphonse" );
        final Friend gaston = new Friend( "Gaston" );
        new Thread(new Runnable() {
            public void run() { alphonse.bow( gaston ); }
        }).start();
        new Thread(new Runnable() {
            public void run() { gaston.bow( alphonse ); }
        }).start();

        System.out.println( "At the end of main" );
    } // end method main

} // end class DeadlockLombok

I will have a few more examples over the next few days.

Image from the Wikipedia page for Jakarta, a province in Indonesia. With Java, the name is usually based on coffee or Indonesia. Image assumed allowed under Fair Use.

 

A Closer Look At Project Lombok

This is a continuation of my look into concurrency in Java.

I found a library called Lombok that uses annotations to reduce boilerplate code. Instead of using annotations for metadata, it uses hidden APIs to alter the class files. Some people do not like this because it is voodoo, but it seems to get the job done. There is a possibility that at some point in the future it will stop working.

For threading, it has an annotation @Synchronized. It has other annotations as well. The voodoo for the @Synchronized annotation is that it will create a private object and inject a synchronized object locking on the private object that it created. There is another version that takes a java.lang.String as a parameter (or element as they are called for annotations). If you use this version, then you provide the name of the object you want to lock on.

Here is what the javadoc says: “Almost exactly like putting the ‘synchronized’ keyword on a method, except will synchronize on a private internal Object, so that other code not under your control doesn’t meddle with your thread management by locking on your own instance.” So I suppose you could do everything that this annotation does for you by providing your own objects. But using Lombok makes your code a lot easier to read.

It would be great if every time you used the “synchronized” keyword the javac compiler created a unique object for that method or block.

In the discussions on LinkedIn, a few people have mentioned that using the synchronized keyword can cause performance issues. I do not know if creating and using a different object degrades performance. I got the impression from the discussions that the performance issue is due to applications repeatedly getting a lock on the same object. I have read that object creation is now cheap, so I do not think that using different private objects for locks would be that big of a deal.

But I do think that it helps prevent deadlocks. I got a few examples of deadlocks from the internet, including one from the Really Big Tutorial, and one from the LinkedIn discussions. I was able to refactor them with Lombok to prevent the deadlocks. I did have to use both forms of the @Synchronized annotation: One with the optional java.lang.String element, and one without. Only using the no-element annotation did not prevent the deadlock.

I will post the deadlock examples I found on the internet as well as my changes with Lombok.

Image from Wikipedia article about Mataram (city), the largest city on Lombok and the capital of the province containing Lombok, assumed allowed under Fair Use.

Looking at Project Lombok

My look into concurrency continues. I am messing around with some of the comments that I have gotten from my posts on LinkedIn and Stack Overflow.

I also found a project called Lombok, named after one of the islands of Indonesia. It uses annotations to replace a lot of boilerplate in Java for a few tasks, including threading. It can handle getters and setters, equals and hashCode and logging as well as synchronization.

A few of the forums that I have been on have recommended looking at something other than the “synchronized” keyword, which Lombok seems to rely on. But it is still worth looking at.

Image from the Wikipedia page for West Nusa Tenggara, the Indonesian province which contains Lombok, assumed allowed under Fair Use.