What is the difference between synchronized methods and blocks?
What is the difference between synchronized
methods and synchronized
statement开发者_C百科s?
If possible, please use an example to make it more clear.
A synchronized method locks the monitor associated with the instance of the class (ie 'this') or the class (if a static method) and prevents others from doing so until the return from the method. A synchronized block can lock any monitor (you tell it which) and can have a scope smaller than that of the encolsing method.
Synchronized blocks are prefered if they don't end up equivalent to the entire scope of the method and/or if they lock something less draconian than the instance (or class if static).
Quotes from the JLS (including example):
JLS 14.19 The synchronized
Statement
A
synchronized
statement acquires a mutual-exclusion lock on behalf of the executing thread, executes a block, then releases the lock. While the executing thread owns the lock, no other thread may acquire the lock.
JLS 8.4.3.6 synchronized
Methods
A
synchronized
method acquires a monitor before it executes. For a class (static
) method, the monitor associated with theClass
object for the method's class is used. For an instance method, the monitor associated withthis
(the object for which the method was invoked) is used.These are the same locks that can be used by the
synchronized
statement; thus, the code:class Test { int count; synchronized void bump() { count++; } static int classCount; static synchronized void classBump() { classCount++; } }
has exactly the same effect as:
class BumpTest { int count; void bump() { synchronized (this) { count++; } } static int classCount; static void classBump() { try { synchronized (Class.forName("BumpTest")) { classCount++; } } catch (ClassNotFoundException e) { ... } } }
So how are they different?
A quotes from Effective Java 2nd Edition, Item 67: Avoid excessive synchronization:
As a rule, you should do as little work as possible inside
synchronized
regions.
The synchronized
modifier for methods, being a syntactic sugar that it is, is applicable in many but not all scenarios. The book goes to discuss in much deeper detail why you should avoid excessive synchronization, but basically by using synchronized
statements, you have much greater control over the boundaries of your synchronized
regions (and if the scenario requires it, you can also choose your own locks).
Unless your method is very simple and/or you need to acquire the this
lock for the entire duration of the method (or the Class
object lock if the method is static
), you should use synchronized
statements to limit the synchronization within the method to only to when you need it (i.e. when you're accessing shared mutable data).
A synchronized
method is a method whose body is encapsulated automatically in a synchronized
block.
Thus, this is equal:
public void foo()
{
synchronized (this)
{
bar();
}
}
public synchronized void foo()
{
bar();
}
synchronized
on method is locked on a this
object. It's equals to synchronized (this) {}
Standard synchronized
is locked on specified object/monitor. With synchronized (***) {}
you can choose an object to use for locking.
A synchronized method is one where you have, in effect, placed the entire body of the function in a synchronized block. A synchronized block has the advantage that you can apply the synchronized block to just a few select statements in the function, instead of to the function as a whole. In general, it is best to make synchronized blocks as short as possible, since time spent in synchronized blocks is time that some other thread might be prevented from doing meaningful work. Another distinction is that you can specify a particular object on which to apply the lock when using a synchronized block whereas with a synchronized method, the object, itself is automatically used as the lock on which synchronization is performed.
精彩评论