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.