I keep seeing code that looks like this:
public void myMethod(args...)
{
synchronized(this)
{
// method code here...
}
}
I'm trying to figure out, is this at all different from:
public synchronized void myMethod(args...)
{
// method code here...
}
I understand the difference in the case where the synchronized(this) { } code block does not contain the entire body of the method, because then it is indicating that some, but not all, of the code in the method is synchronized on this object instance.
But in the case that I showed above, where the synchronized(this) { } code block includes the entire body of the method, is there any difference between that and just declaring the method synchronized?
No difference.
ReplyDeleteMinor variation for static methods:
public class MyJavaThing {
public static void myMethod() {
synchronized(MyJavaThing.class) {}
}
}
same as:
public static synchronized void myMethod() {
}
Wow posting comments painful here! I like to press space bar twice after a full stop, and I like to use cursor keys when editing. This comment widgit is blocking me.
accordingly to Brian Goetz's book (Concurrency in Practice), Chap 2.3.1, this is equivalent ("A synchronized method is a shorthand for a synchronized block that spans an entire method body, and whose lock is the object on which the method is being invoked")
ReplyDeleteI figure there's no observable difference if the synchronized{} block covers all of the method.
ReplyDeletePerhaps some basis points of execution efficiency (I'd expect synchronized method to be a bit faster but this purely guesswork); but otherwise no difference.
With very old versions of javadoc, if you put "synchronized" on the method call that would show up in the generated API docs.
ReplyDeleteMost IDEs deal with static <-> non-static refactorings slightly differently depending on whether you have a synchronized block vs a synchronized keyword on a method.
Whether the different forms generate different byte code depends on the compiler; semantically they are the same.
As someone relatively new to the world of Java, my humble opinion is synchronized(this) is preferable because it lets someone working on the code modify the method body for purposes such as quick debugging without having to understand the consequences of their debug code or whatnot being synchronized.
ReplyDeleteGreat blog, btw.
In the ancient (interpreted-only) days there was some small performance advantage of synchronized methods over synchronized blocks because synchronized blocks required more bytecode; this is now ancient history.
ReplyDeleteIn the less ancient days the synchronized-ness of methods appeared in the Javadoc; this was stopped a while ago as well (1.3?) because this is an implementation detail, not an interface contract.
As to programming style, consider synchronized methods a convenient shorthand; use it where it fits. Sometimes you want a smaller scope for holding locks than a whole method (either for performance or correctness reasons); in those cases use a synchronized(this) block is indicated. If you are using a different lock to guard data than the 'this' lock, then synchronized blocks are your only option.