23

I have used the synchronized keyword and re-entrant locks in Java, but I don't understand how they differ, or which is appropriate for a given situation.

How do I decide when should I use synchronized and when I should use re-entrant locks?

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
noMAD
  • 7,744
  • 19
  • 56
  • 94

3 Answers3

28

A ReentrantLock is:

A reentrant mutual exclusion Lock with the same basic behavior and semantics as the implicit monitor lock accessed using synchronized methods and statements, but with extended capabilities.

Extended capabilities include:

  1. The ability to have more than one condition variable per monitor. Monitors that use the synchronized keyword can only have one. This means reentrant locks support more than one wait()/notify() queue.
  2. The ability to make the lock fair. Synchronized blocks are unfair.

    "[fair] locks favor granting access to the longest-waiting thread. Otherwise this lock does not guarantee any particular access order."

  3. The ability to check if the lock is being held.
  4. The ability to get the list of threads waiting on the lock.

The disadvantages of reentrant locks are:

  1. Need to add import statement.
  2. Need to wrap lock acquisitions in a try/finally block. This makes it more ugly than the synchronized keyword.
  3. The synchronized keyword can be put in method definitions which avoids the need for a block which reduces nesting.

Summary

The synchronized keyword is syntactically nicer, but the Reentrant lock has more features.

Community
  • 1
  • 1
Jay
  • 9,314
  • 7
  • 33
  • 40
3

This site clearly mentioned difference between ReentrantLock and synchronized keyword in Java. I just copy and paste from there.

http://javarevisited.blogspot.in/2013/03/reentrantlock-example-in-java-synchronized-difference-vs-lock.html

1) Another significant difference between ReentrantLock and synchronized keyword is fairness. synchronized keyword doesn't support fairness. Any thread can acquire lock once released, no preference can be specified, on the other hand you can make ReentrantLock fair by specifying fairness property, while creating instance of ReentrantLock. Fairness property provides lock to longest waiting thread, in case of contention.

2) Second difference between synchronized and Reentrant lock is tryLock() method. ReentrantLock provides convenient tryLock() method, which acquires lock only if its available or not held by any other thread. This reduce blocking of thread waiting for lock in Java application.

3) One more worth noting difference between ReentrantLock and synchronized keyword in Java is, ability to interrupt Thread while waiting for Lock. In case of synchronized keyword, a thread can be blocked waiting for lock, for an indefinite period of time and there was no way to control that. ReentrantLock provides a method called lockInterruptibly(), which can be used to interrupt thread when it is waiting for lock. Similarly tryLock() with timeout can be used to timeout if lock is not available in certain time period.

4) ReentrantLock also provides convenient method to get List of all threads waiting for lock.

Hrishikesh Mishra
  • 3,295
  • 3
  • 27
  • 33
0

I have always thought of synchronization as "the hack of least resistance". It just works and most everyone understands how it works, but it has some weaknesses that could affect your design under heavy concurrency. Not least of which is any client effectively has direct access to your object's synchronization lock meaning if they grab it and hold it other clients can't. In other words, the locking implemented by default synchronization effectively "publishes" you object's internal locking mechanism. Yuk. Its like setting yourself up for self-inflicted denial-of-service.

If you make the reentrant lock internal to your class (or just don't use the synchronized but do something like synchronize on some internal object that you new up in your constructor everywhere that you want synchronization), you remove this side-effect of publishing your internal locking mechanism, with the added complexity of you having to remember where to apply this internal synchronization as your class evolves.

Bob Kuhar
  • 10,838
  • 11
  • 62
  • 115
  • "any client effectively has direct access to your object's synchronization lock" only if you apply the `synchronized` modifier to an accessible method, not if you use a `synchronized` block on an inaccessible lock object. – Raedwald Jan 31 '12 at 01:30
  • Yeah. That's what I said. If you use the default synchronized keyword on your methods, you are effectively publishing your locks. To get around this, make the synchronized block internal. – Bob Kuhar Jan 31 '12 at 03:49