This is a cliche, but if it were just the more common ones, I wouldn’t need to record this article, and there’s a subtle difference today when writing code for both.

Conventional difference

  • ReentrantLock is more flexible, providing timeout acquisition locks that can be broken. Provides both unfair and unfair locks, while synchronized is merely unfair locks.
  • In usage, ReentrantLock must release the lock manually and can only modify code blocks. Synchronized, on the other hand, does not release the lock manually and can otherwise modify methods.

Another difference is that synchronized threads are blocked, whereas ReentrantLock threads are in a waiting state

Doubt point

Is ReentrantLock really better than synchronized?

I wrote a simple demo

public class LockDemo {

    static ReentrantLock lock = new ReentrantLock(false); public static void main(String[] args) { syncTest(); // lockTest(); } public static voidsyncTest() {
        for (int i = 0; i < 10; i++) {
            new Thread() {
                @Override
                public void run() {
                    synchronized (lock) {
                        System.out.println(Thread.currentThread().getName() + "Start locking");
                        try {
                            Thread.sleep(2 * 1000);
                        } catch (Exception e) {
                            e.printStackTrace();
                        } finally {
                            System.out.println(Thread.currentThread().getName() + "Unlocked");

                        }
                    }
                }
            }.start();
        }
    }

    public static void lockTest() {
        for (int i = 0; i < 10; i++) {
            new Thread() {
                @Override
                public void run() {
                    lock.lock();
                    System.out.println(Thread.currentThread().getName() + "Start locking");
                    try {
                        Thread.sleep(2 * 1000);
                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        System.out.println(Thread.currentThread().getName() + "Unlocked"); lock.unlock(); } } }.start(); }}}Copy the code

The results are as follows:

Synchonized, the thread states are only time_waiting and blocked. When the thread that acquired the lock completes execution, the other threads will fight for the lock again together

ReentrantLock’s unfair lock test, even though I’m using an unfair lock, looks fair. The internal thread is in a waiting state

As for whether the performance is high, I think the performance of acquiring a lock by a single thread is higher than that by multiple threads. The optimization made by synchronized lock is only made by a single thread or two threads, and once upgraded to a heavyweight lock, those optimizations are no longer effective.

This is a personal guess, of course.

The last

Look at the source code inside ReentrantLock to see the details.

  • Locksupport.park, the thread will enter the waiting state
  • ReentrantLock uses an unfair lock, but if a new thread attempts to acquire the lock, only the current thread will fight for it.