GeeCON Prague 2014*
The moose likes Threads and Synchronization and the fly likes Synchronized Methods and Synchronized Blocks Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Synchronized Methods and Synchronized Blocks" Watch "Synchronized Methods and Synchronized Blocks" New topic
Author

Synchronized Methods and Synchronized Blocks

Ashok Srinivasan
Greenhorn

Joined: Jun 24, 2004
Posts: 15
Plz give me the difference between the synchronized methods and the synchronized blocks in detailed manner.
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
You mean like this ?

- Peter
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

Best practice is to use synch blocks and not synch methods. A synchronized method is synching on the 'this' object which is always public so to speak.

Treat your monitor object with the same respect you show every other class member. Restrict its access as much as possible. Which is how we get to the conclusion of not using synchronized methods ever.
Adeel Ansari
Ranch Hand

Joined: Aug 15, 2004
Posts: 2874
in synchronized method you can't specify a particular object, in block you can:

synchronized(obj){
..
..
}
and as Gilbert said its better to use synchronized block rather than synchronized method
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
Gilbert - interesting rationale, one I had not heard but will remember. I just assumed blocks were preferred over methods because you have the opportunity to make the blocks shorter. Sync only the lines of code that require it instead of a whole method, making what you're locking and why more explicit and hopefully making the lock duration shorter.


A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by CL Gilbert:
Best practice is to use synch blocks and not synch methods. A synchronized method is synching on the 'this' object which is always public so to speak.
I've been chewing on this for a day, and I'm not sure I buy it.

There are two levels at which you can look at this statement. The first is as a simple statement of fact, and as such it's nonsense. There is no generally accepted "best practice" which prefers synchronized blocks to methods. Or if there is, someone should tell Sun because the JDK is full of synchronized methods; also tell Josh Bloch because Effective Java's chapter 9 is full of them too; tell Doug Lea because Tiger's brand new java.util.concurrent package has synchronized methods in both code and examples; Peter Haggar (Practical Java) as he even argues for synchronized methods in preference to blocks; and so on.

The more useful second level is to see whether you can make a valid case for such a best practice and, truth be told, I definitely see your point. There's a thoughtful little discussion on the C2 wiki as well. As pointed out there, one of the problems is that method synchronization is more efficient. I would add that it is also more readable than a synchronized block. Finally, it is perhaps worth mentioning that sometimes you cannot get around making synchronization part of the public API, as for example in a Collection (you need it to make iteration threadsafe).

Ultimately I think I'd still choose synchronized methods in many cases because I feel that the readability difference is real, whereas the visibility argument is mostly academic: I've never heard of anyone spotting the problem described on the C2 page "in the wild". But whatever your thoughts are, it's easy to see why a strong best practice never got established in this matter.

- Peter
[ August 30, 2004: Message edited by: Peter den Haan ]
Peter den Haan
author
Ranch Hand

Joined: Apr 20, 2000
Posts: 3252
Originally posted by Stan James:
[...]I just assumed blocks were preferred over methods because you have the opportunity to make the blocks shorter.
That's not necessarily a reason to use blocks, it just might be a reason to break up your method. Often the critical section deserves its own private method on functional/coherence grounds alone; trivial to then synchronize it.

There are good reasons to use synchronized blocks. This is not one of them.

- Peter
Adeel Ansari
Ranch Hand

Joined: Aug 15, 2004
Posts: 2874
how about this?

- when a thread is executing a synchronized block no other thread (using the same instance) can enter that block before it comes out.

- or the other thread (using the same instance) can enter the block but can not access that particular object, which we specified in synchronized(obj), simultaneously. and wait for the turn.

which one is right??
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Adeel, your question doesn't seem to be related to the original subject of this thread. Please continue discussion here: http://www.coderanch.com/t/232676/threads/java/semantic-synchronization


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

Originally posted by Peter den Haan:
I've been chewing on this for a day, and I'm not sure I buy it.

There are two levels at which you can look at this statement. The first is as a simple statement of fact, and as such it's nonsense. There is no generally accepted "best practice" which prefers synchronized blocks to methods. Or if there is, someone should tell Sun because the JDK is full of synchronized methods; also tell Josh Bloch because Effective Java's chapter 9 is full of them too; tell Doug Lea because Tiger's brand new java.util.concurrent package has synchronized methods in both code and examples; Peter Haggar (Practical Java) as he even argues for synchronized methods in preference to blocks; and so on.


I consider a synchronized method a violation of the principle of encapsulation. It exposes a member of the class which in this case happens to also be the class itself. This member is the lock object that the synchronized method is using.

Do you not agree?

and as we consider encapsulation 'best practice' I just extended that to this synchronized methods situation.

And yes, Sun does violate this. For instance, take a look at Thread.join().



now if you have extended the thread class, and are using synchronized methods, then you are using the same lock object for seperate purposes.

Sun can not change this because if Sun suddenly changes from method synchronization to block synchronization in the Thread class, it can affect the behavior of any program that was also using method synchronization in an extension of Thread.

Plus all the rest of the problems you get when you violate encapsulation. So perhaps I should stop calling it 'best practice' and start calling it a violation of encapsulation since that is what it is.
Daniel Mayer
Ranch Hand

Joined: Sep 09, 2004
Posts: 103
Originally posted by CL Gilbert:
So perhaps I should stop calling it 'best practice' and start calling it a violation of encapsulation since that is what it is.


I agree that it weakens encapsulation. Encapsulation is not a goal in itself, though - it is just one of the tools we use to make our programs easier to understand, maintain and extend. And it also comes with a cost, as it can make a design more complex.

Therefore I think there needs to be a balance. I am not sure where the balance is in this case - I didn't yet have any problems with synchronized methods, but I am far from an expert in this matter. I suspect it might even depend on the kind of system you are working on.

I certainly wouldn't accept encapsulation as the sole argument against method synchronization. I would be interested in the kind of problems that arise due to it, though, so that I can monitor my systems for them and make informed, situational decisions about it.
Warren Dew
blacksmith
Ranch Hand

Joined: Mar 04, 2004
Posts: 1332
    
    2
Daniel Mayer:

I agree that it weakens encapsulation. Encapsulation is not a goal in itself, though - it is just one of the tools we use to make our programs easier to understand, maintain and extend.

Yes. For example, public methods also violate encapsulation ... but it would be pretty inconvenient to avoid them entirely.

I agree that mixing synchronized methods and synchronized blocks freely can increase the possibility of deadlock. Using either one exclusively reduces that likelihood, but does not eliminate it, since either way, synchronized code can still get a second lock by calling into a method on another object that also contains a synchronized block.

I'm not actually convinced that the way to deal with deadlocks is just to make them less likely, though. A less likely deadlock may actually be worse, as it has a better chance of being missed in QA and being found by an actual customer instead ... plus, it will be more difficult to duplicate and thus to debug. I prefer an analytical approach where one tries to eliminate the possibility of deadlock, rather than just reduce their likelihood.

Some uses of encapsulated mutexes can help a lot with this approach, but simple heuristics about whether to use synchronized methods do not.
Daniel Mayer
Ranch Hand

Joined: Sep 09, 2004
Posts: 103
Warren, are you saying that the use of synchronized methods inherently increases the likelihood of deadlocks?
Warren Dew
blacksmith
Ranch Hand

Joined: Mar 04, 2004
Posts: 1332
    
    2
Daniel Mayer:

Warren, are you saying that the use of synchronized methods inherently increases the likelihood of deadlocks?

I wouldn't exactly put it that way. With sufficient care, synchronization (methods or blocks) can be used without causing a deadlock.

However, if one has code that can potentially deadlock, using longer synchronized blocks - for example, entire methods rather than a few statements - may make that deadlock likely to manifest itself sooner.

Take the following example:



Now, what happens when a.deadlock_prone() is called in thread 1, while b.deadlock_prone() is called in thread 2? Well, you can have a deadlock if thread 1 calls a.deadlock_prone(), gets to the call to brief_call(), then gets switched out in favor of thread 2. Now thread two calls b.deadlock_prone(), gets through its call to brief_call(), and calls "other_object.brief_lock()" - which, since b.other_object is a, is a call to a.brief_lock(). Now thread 2 gets to the synchronized block in a.brief_lock(), but it can't get the lock on a's mutex, because thread 1 still has that lock. Meanwhile, thread 1 gets switched back in, completes its call to brief_call(), and calls brief_lock() on object b. Unfortunately, it also gets blocked when it reaches the synchronized block in b.brief_lock(), because thread 2 still has the lock on b's mutex. Deadlock.

However, this only happens if the first switch between the threads is during thread 1's call to brief_call(). If the switch happens a bit earlier, say during thread 1's call to time_consuming_call(), thread 1 doesn't have the lock on its mutex yet. As a result, thread 2, when it gets switched in, can grab the mutexes for both objects. It can then run to completion, after which thread 1 can run to completion. Sounds good, right?

Not so fast. If brief_call() is brief enough, the chance of a deadlock may be quite small. In practice, what that means it that it may be missed in testing. However, the deadlock is still possible, and the odds are it will eventually happen. Once your server is up and running and serving hundreds or thousands of users, you start seeing the deadlock - by Murphy's law, especially when it causes the biggest problems for your customer, and they get most upset at you. But it's really hard duplicate the bug in the lab, because you don't have gazillions of users to help you test, so you can't find it to fix it. Bad situation.

Contrast this with the situation when you synchronize both the methods, rather than having separate internal synchronized blocks. This means that deadlock_prone() now synchronizes before the call to time_consuming_call(), rather than after it. It becomes much more likely that thread 1 will already have its lock on object a during a thread switch, since a thread switch during time_consuming_call() will now happen after thread 1 has its lock on a. That means the deadlock happens a bigger percentage of the time, hopefully often enough to show up during testing. Perhaps you can fix it before the customer ever sees it.

I'm not actually sure this is an argument for or against using synchronized functions, or for using longer or shorter synchronized blocks. I think the right approach is instead to be extremely careful with synchronization, to avoid writing the deadlock prone code in the first place. Fine tuning synchronization for efficiency can wait until the code needs to be optimized.
[ September 12, 2004: Message edited by: Warren Dew ]
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
Warren, are you saying that the use of synchronized methods inherently increases the likelihood of deadlocks?

I wouldn't exactly put it that way. With sufficient care, synchronization (methods or blocks) can be used without causing a deadlock.


Isn't the opposite true too ... if there are no synchronized blocks (or calls to external things that can block, like databases) you won't get deadlocks? Do synchronized blocks or methods raise the likelihood from zero to non-zero? That can be huge sometimes.
Warren Dew
blacksmith
Ranch Hand

Joined: Mar 04, 2004
Posts: 1332
    
    2
Stan James:

Isn't the opposite true too ... if there are no synchronized blocks (or calls to external things that can block, like databases) you won't get deadlocks?

Yes, absolutely true. If you never synchronize, you don't get deadlocks. It's just that I didn't want to appear to be saying you should never synchronize, since that can result in corrupted data instead.
Daniel Mayer
Ranch Hand

Joined: Sep 09, 2004
Posts: 103
Originally posted by Warren Dew:
I'm not actually sure this is an argument for or against using synchronized functions, or for using longer or shorter synchronized blocks. I think the right approach is instead to be extremely careful with synchronization, to avoid writing the deadlock prone code in the first place. Fine tuning synchronization for efficiency can wait until the code needs to be optimized.


I fully agree.

Thanks for the example - it reminded me of a similar problem we recently found in our connection pool, which made use of a wait- notify pair to wait for the connection to be available. Unfortunately, with a new in memory database, the notify would be called before the wait - the database simply was "too fast". The real problem, of course, was improper usage of wait and notify.
Daniel Mayer
Ranch Hand

Joined: Sep 09, 2004
Posts: 103
Originally posted by Warren Dew:
Stan James:

Isn't the opposite true too ... if there are no synchronized blocks (or calls to external things that can block, like databases) you won't get deadlocks?

Yes, absolutely true. If you never synchronize, you don't get deadlocks. It's just that I didn't want to appear to be saying you should never synchronize, since that can result in corrupted data instead.


The question is, is there a difference in liklehood of deadlocks between synchronize blocks and synchronized methods?

I don't think there inherently is. I will admit, though, that using synchronize blocks forces me to think more about what lock I really need (the same as that other method or not?). It also gives me a way of expessing the reason for synchronisation, via the name of the lock variable.

I think I will be using blocks more often in the future...
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

Originally posted by Daniel Mayer:


I agree that it weakens encapsulation. Encapsulation is not a goal in itself, though - it is just one of the tools we use to make our programs easier to understand, maintain and extend. And it also comes with a cost, as it can make a design more complex.

Therefore I think there needs to be a balance. I am not sure where the balance is in this case - I didn't yet have any problems with synchronized methods, but I am far from an expert in this matter. I suspect it might even depend on the kind of system you are working on.

I certainly wouldn't accept encapsulation as the sole argument against method synchronization. I would be interested in the kind of problems that arise due to it, though, so that I can monitor my systems for them and make informed, situational decisions about it.



Well I guess. That is why i say 'best practice' and not 'only practice.' But I dont think its a good idea at all. Look at the example I gave. Sun is locked into this now. It has nothing to do with deadlock per se. Sun can't know how their change would affect any program. perhaps the program deadlocks, but the authors never knew why, and added some code to compensate. Its just a bad position to be in, and I can't imagine why anyone would think it acceptable.

I don't find using method synchronization makes the design significantly more complex. Its one more protected variable, that is all.


Encapsulation is indeed the sole argument against method synchronization.
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

Originally posted by Warren Dew:
Daniel Mayer:

I agree that it weakens encapsulation. Encapsulation is not a goal in itself, though - it is just one of the tools we use to make our programs easier to understand, maintain and extend.

Yes. For example, public methods also violate encapsulation ... but it would be pretty inconvenient to avoid them entirely.
...


How so?

Originally posted by Warren Dew:
Daniel Mayer:
...I agree that mixing synchronized methods and synchronized blocks freely can increase the possibility of deadlock. Using either one exclusively reduces that likelihood, but does not eliminate it, since either way, synchronized code can still get a second lock by calling into a method on another object that also contains a synchronized block.


I do not agree. The issue is with behavior in general, deadlock is just a different behavior.
Warren Dew
blacksmith
Ranch Hand

Joined: Mar 04, 2004
Posts: 1332
    
    2
CL Gilbert:

Look at the example I gave. Sun is locked into this now. It has nothing to do with deadlock per se. Sun can't know how their change would affect any program. perhaps the program deadlocks, but the authors never knew why, and added some code to compensate. Its just a bad position to be in, and I can't imagine why anyone would think it acceptable.

But exactly the same argument would be true if Sun had used internal synchronization, rather than simply declaring the method synchronized. Whichever way they write it, they can't switch to the other later. And in the particular case of Thread.join, not using any synchronization at all would be even worse, because it could allow other Thread methods to be half completed when the thread went away.

I personally think that for commonly used classes that are part of the language or library, using synchronized methods is better than using internal locks, because synchronized methods more clearly document what locks are occurring. That way, anyone using the library can more easily figure out what's going on and can write their own code accordingly to avoid deadlocks.

For one's own code, that argument may or may not apply.
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

Originally posted by Warren Dew:
CL Gilbert:

Look at the example I gave. Sun is locked into this now. It has nothing to do with deadlock per se. Sun can't know how their change would affect any program. perhaps the program deadlocks, but the authors never knew why, and added some code to compensate. Its just a bad position to be in, and I can't imagine why anyone would think it acceptable.

But exactly the same argument would be true if Sun had used internal synchronization, rather than simply declaring the method synchronized. Whichever way they write it, they can't switch to the other later. And in the particular case of Thread.join, not using any synchronization at all would be even worse, because it could allow other Thread methods to be half completed when the thread went away.

I personally think that for commonly used classes that are part of the language or library, using synchronized methods is better than using internal locks, because synchronized methods more clearly document what locks are occurring. That way, anyone using the library can more easily figure out what's going on and can write their own code accordingly to avoid deadlocks.

For one's own code, that argument may or may not apply.



Synchronization is an implementation detail which is exposed only as thread safety. It should not be considered part of the contract. That is why the keyword 'synchronized' is not useable in an interface.

Is it that you don't believe in encapsulation, don't feel its terribly important, or don't think its being violated here?
Rovas Kram
Ranch Hand

Joined: Aug 08, 2003
Posts: 135

Originally posted by CL Gilbert:
Encapsulation is indeed the sole argument against method synchronization.



Gilbert,
If Sun had made it so that a synchronized method locked on a protected object rather than 'this' would that satisfy your encapsulation concerns? Or would encapsulation still be violated because the sychronization is being exposed?
Warren Dew
blacksmith
Ranch Hand

Joined: Mar 04, 2004
Posts: 1332
    
    2
CL Gilbert:

Is it that you don't believe in encapsulation, don't feel its terribly important, or don't think its being violated here?

By my definition of encapsulation, or by yours?

I define encapsulation as "keeping the implementation private" - including the code as well as data. From this point of view, simply making the locks private does not help with encapsulation, because the fact of synchronization is still public to any code whose thread of execution includes calls into the object, as Rovas points out. Simply replacing public locks with private locks only provides a false sense of security.

Maybe some day people will figure out how to put together a programming language that will allow us to encapsulate threading the way classes and objects allow us to encapsulate data, but it hasn't happened yet.
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

Originally posted by Rovas Kram:



Gilbert,
If Sun had made it so that a synchronized method locked on a protected object rather than 'this' would that satisfy your encapsulation concerns? Or would encapsulation still be violated because the sychronization is being exposed?


That would indeed satisy me. Though I am certainly not asking for such a change. I believe in programmers freedom to make their own choices. I only assert that it would be a best practice not to use synchronized methods in their current incarnation.
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

Originally posted by Warren Dew:
CL Gilbert:

Is it that you don't believe in encapsulation, don't feel its terribly important, or don't think its being violated here?

By my definition of encapsulation, or by yours?

I define encapsulation as "keeping the implementation private" - including the code as well as data. From this point of view, simply making the locks private does not help with encapsulation, because the fact of synchronization is still public to any code whose thread of execution includes calls into the object, as Rovas points out. Simply replacing public locks with private locks only provides a false sense of security.

Maybe some day people will figure out how to put together a programming language that will allow us to encapsulate threading the way classes and objects allow us to encapsulate data, but it hasn't happened yet.



I believe we share the same definition of encapsulation. Do you believe otherwise?

I don't understand how private locks yields public synchronization? Any thread that calls into this object has no knowledge of its internal synchronization. That the thread may have to wait is part of the contract of the called method, not the implementation.

For instance, the fact that inputstreams can block is part of their contract. You can not simply change the inputstream so that it does not block without violating its contract. Therefore the fact of blocking is not an implementation detail, but a contract detail. While the method of blocking is an implementation detail.

Of course it is also upto the programmer to draw a clear line between his implementation and his contract. You cant really encapsulate until you define this.
 
GeeCON Prague 2014
 
subject: Synchronized Methods and Synchronized Blocks