Aditya
Aditya

Reputation: 1043

Advantages of Synchronization over Locks API

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

Answers (2)

Stephen C
Stephen C

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

Shepard
Shepard

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

Related Questions