Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReentrantLock vs synchronized on CPU level?

Is there a difference between 'ReentrantLock' and 'synchronized' on how it's implemented on CPU level? Or do they use the same 'CAS' approach?

like image 624
user_x Avatar asked Apr 02 '16 08:04

user_x


People also ask

What is the difference between ReentrantLock and synchronized?

As stated earlier, the main difference between synchronized and ReentrantLock is the ability to trying to lock interruptibly, and with a timeout. The thread doesn't need to block infinitely, which was the case with synchronized.

How locks are better than synchronized?

Lock framework works like synchronized blocks except locks can be more sophisticated than Java's synchronized blocks. Locks allow more flexible structuring of synchronized code.

What is the difference between lock and ReentrantLock?

Lock is an interface. It defines a set of methods that all locks should have. ReentrantLock is a concrete class that implements the Lock interface.

Why is ReentrantLock called reentrant?

As the name says, ReentrantLock allows threads to enter into the lock on a resource more than once. When the thread first enters into the lock, a hold count is set to one. Before unlocking the thread can re-enter into lock again and every time hold count is incremented by one.


2 Answers

If we are talking about ReentrantLock vs synchronized (also known as "intrinsic lock") then it's a good idea to look at Lock documentation:

All Lock implementations must enforce the same memory synchronization semantics as provided by the built-in monitor lock:

  • A successful lock operation acts like a successful monitorEnter action
  • A successful unlock operation acts like a successful monitorExit action

So in general consider that synchronized is just an easy-to-use and concise approach of locking. You can achieve exactly the same synchronization effects by writing code with ReentrantLock with a bit more code (but it offers more options and flexibility).

Some time ago ReentrantLock was way faster under certain conditions (high contention for example), but now Java uses different optimizations techniques (like lock coarsening and adaptive locking) to make performance differences in many typical scenarios barely visible to the programmer.

There was also done a great job to optimize intrinsic lock in low-contention cases (e.g. biased locking). Authors of Java platform do like synchronized keyword and intrinsic-locking approach, they want programmers do not fear to use this handy tool (and prevent possible bugs). That's why synchronized optimizations and "synchronization is slow" myth busting was such a big deal for Sun and Oracle.

"CPU-part" of the question: synchronized uses a locking mechanism that is built into the JVM and MONITORENTER / MONITOREXIT bytecode instructions. So the underlying implementation is JVM-specific (that is why it is called intrinsic lock) and AFAIK usually (subject to change) uses a pretty conservative strategy: once lock is "inflated" after threads collision on lock acquiring, synchronized begin to use OS-based locking ("fat locking") instead of fast CAS ("thin locking") and do not "like" to use CAS again soon (even if contention is gone).

ReentrantLock implementation is based on AbstractQueuedSynchronizer and coded in pure Java (uses CAS instructions and thread descheduling which was introduced it Java 5), so it is more stable across platforms, offers more flexibility and tries to use fast CAS appoach for acquiring a lock every time (and OS-level locking if failed).

So, the main difference between these locks implementations in terms of performance is a lock acquiring strategy (which may not exist in specific JVM implementation or situation).

And there is no general answer which locking is better + it is a subject to change during the time and platforms. You should look at the specific problem and its nature to pick the most suitable solution (as usually in Java)

PS: you're pretty curious and I highly recommend you to look at HotSpot sources to go deeper (and to find out exact implementations for specific platform version). It may really help. Starting point is somewhere here: http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/87ee5ee27509/src/share/vm/runtime/synchronizer.cpp

like image 137
Cootri Avatar answered Oct 02 '22 04:10

Cootri


The ReentrantLock class, which implements Lock, has the same concurrency and memory semantics as synchronized, but also adds features like lock polling, timed lock waits, and interruptible lock waits. Additionally, it offers far better performance under heavy contention.

Source

Above answer is extract from Brian Goetz's article. You should read entire article. It helped me to understand differences in both.

like image 32
Vipin Avatar answered Oct 02 '22 04:10

Vipin