Reputation: 1043
Every blog or Explanation I see advantages of Locks API over Synchronization.
I want to know are there any advantages of Synchronization over locks, or any scenario where I should prefer Synchronization and not Locks.
Upvotes: 3
Views: 146
Reputation: 718698
In addition to @Shepard's answer, using synchronized
is less error prone. Consider these mistakes which can lead to locks not being released:
final private Lock lock = new ReentrantLock();
public void myMethod() {
lock.lock();
// concurrent stuff
}
public void myMethod2() {
lock.lock();
// concurrent stuff that might throw an unchecked exception
lock.unlock();
}
public void myMethod3() {
lock.lock();
try {
// concurrent stuff
lock.unlock();
} catch ( ... ) {
...
} finally {
...
}
}
The first one is liable to show up in testing, but the latter two may not.
You can't make any of these mistakes with synchronized
.
However, Lock
is useful despite these considerations:
Locks allow you to implement different locking strategies such as non-reentrant locking and multi-reader / single-writer locking.
Locks allow you to hold locks across scope / block structure boundaries. (This makes your code harder to reason about, but it is necessary for some use-cases; e.g. event-based designs where locks need to be held across multiple event handlers.)
The Lock API allows you to test a lock, acquire a lock without blocking, or with a timeout, and define Condition
objects.
Upvotes: 6
Reputation: 811
Do you mean the synchronized statement and methods keyword? The main advantages of implicit locking is that requires less code and unlocks automatically when leaving its scope. For simple lock/wait operations it's the perfect solution.
So the following code
public void myMethod() {
synchronized(this) {
// concurrent stuff
}
}
is perfectly equivalent to
final private Lock lock = new ReentrantLock();
public void myMethod() {
lock.lock();
try {
// concurrent stuff
}
finally {
lock.unlock();
}
}
and
synchronized public void myMethod() {
// concurrent stuff
}
You can also use different objects for synchronization (they are not affected in any way, being only control points):
final static private Object sync = new Object();
public void method1() {
synchronized(sync) {
// concurrent code involving static members
}
}
public void method2() {
synchronized(this) {
// concurrent code affecting this instance
}
}
Upvotes: 7