0

I am reading comparison between Reentrant locks and synchronization blocks in java. I am going through the various resources on internet. One disadvantage that I discovered using Reentrant locks over synchronization blocks is that in previous one, you have to explicitly use try finally block to call unlock method on the acquired lock in the finally block, as it might be possible that your critical section of code might throw exception and it can cause big trouble, if thread doesn't releases the lock, While in the latter one, JVM itself takes care of releasing the lock in case of exception.

I am not very much convinced with this disadvantage, because it's not a big deal to use try finally block.As we have been using it for long time for ex(stream closing etc). Can somebody tell me some other disadvantages of Re-entrant locks over synchronized blocks?

Vinit89
  • 583
  • 1
  • 7
  • 31
  • 1
    There aren't any other disadvantages: a `synchronized` block is essentially a `ReentrantLock` without the clutter. But that is enough reason: you should not complicate your code unnecessarily. – assylias Apr 20 '14 at 08:16

2 Answers2

0

A ReentrantLock is a different tool for a different use-case. While you can use both for most synchronization issues (that's what they are made for), the come with different advantages and disadvantages.

Synchronized is at most simple: you write synchronized and that's it. With modern JVMs it is reasonable fast, but has the drawback that it puts all threads that try to enter a synchronized block on hold, whether they actually need to or not. If you use synchronized too often, this can dramatically reduce the speed of multi-threading, worst case down to a point where single-threaded execution would have been faster.

As threading issues only occur if someone is writing while someone else is reading/writing the same data section, programs often run into the problem, that they could theoretically run without synchronization, because most threads just read, but there is this one occasional write, which enforces the synchronized block. This is what the Locks were made for: you have a finer control over when you actually synchronize.

The basic ReentrantLock allows - beside a fair parameter in the constructor - that you can decide when you release the lock, and you can do it at multiple points, so when it suits you best. Other variations of it like the ReentrantReadWriteLock allow you to have many unsynchronized reads, except if there is a write. The downside is that this is solved in Java code, which makes it noticeably slower than the "native" synchronized block. That said: you should only use it, if you know that the optimization gain using this lock is bigger than the loss.

Under normal situations you can only tell the difference in speed if you actually monitor it, by running a profiler to check the speed before and afterwards in a sophisticated way.

TwoThe
  • 13,879
  • 6
  • 30
  • 54
0

synchronized is almost always faster for low or minimal contention, because it allows JVM to perform some optimizations such as biased locking, lock elision and others. Here are some more details how it works:

Let's assume some monitor is held by thread A, and thread B requests this monitor. In that case monitor will change its state to inflated. Saying short, it means that all threads trying to acquire this monitor, will be put to wait set at OS level, which is quite expensive.

Now, if thread A released monitor before thread B requested it, so-called rebias operation will be performed by cheap (on modern CPU) compare-and-swap operation.

Let's take a look at ReentrantLock now. Each thread calls lock() or lockInterruptibly() method cause locking attempt done via CAS operation.

Conclusion: in low contention cases, prefer synchronized. In high contention cases, prefer ReentrantLock. For all cases between, it is hard to say for sure, consider performing benchmarks to find out which solution is faster.

Alexey Malev
  • 6,408
  • 4
  • 34
  • 52