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.