1. Introduction of already

ReentrantLock is an implementation of the Lock interface class, which implements AQS through the internal class Sync. Compared with Synchronized, both are reentrant locks, but the difference lies in that ReentrantLock can be more flexible. The locking and unlocking of Synchronized are completed by JVM.

2. Principle of ReetrantLock

2.1 Unfair Lock

Unfair locking is the default way to obtain locks.

Unfair lock When obtaining the synchronization status, the system checks whether the current thread is the thread that acquires the lock. If so, the system increases the synchronization value and returns true, indicating that the synchronization status is successfully obtained.

        final boolean nonfairTryAcquire(int acquires) {
            // Get the current thread
            final Thread current = Thread.currentThread();
            // Get the synchronization state of the current thread
            int c = getState();
            // State 0 indicates that the current lock is not occupied by another thread
            if (c == 0) {
                // Set the current lock state to acquires
                if (compareAndSetState(0, acquires)) {
                    // Set the current thread to hold an exclusive lock
                    setExclusiveOwnerThread(current);
                    return true; }}// Indicates that the current thread is the thread that acquires the lock again
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }
Copy the code

2.2 fair lock

        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            // The synchronization status of the current thread is 0, trying to acquire the lock
            if (c == 0) {
                // Check whether there are other threads in the CLH queue. If no current thread succeeds in acquiring the lock, the current thread needs to wait
                if(! hasQueuedPredecessors() && compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true; }}else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false; }}Copy the code

The difference between a fair lock and a non-fair lock is that a fair lock determines whether there are other threads in the CLH queue, while a non-fair lock attempts a CAS operation to change the synchronization state.

2.3 Lock Release

The lock is released only when the synchronization status is 0, and all previous operations return false.

        protected final boolean tryRelease(int releases) {
            int c = getState() - releases;
            if(Thread.currentThread() ! = getExclusiveOwnerThread())throw new IllegalMonitorStateException();
            boolean free = false;
            if (c == 0) {
                free = true;
                setExclusiveOwnerThread(null);
            }
            setState(c);
            return free;
        }
Copy the code
ReentrantLock Synchronized
Lock implementation mechanism Rely on AQS Monitor mode
flexibility Supports response interrupts, timeouts, and attempts to acquire locks inflexible
Release form It must appear that unlock() is called to release the lock Automatic release monitor
The lock type Fair locks & Unfair locks Not fair lock
Conditions of the queue Multiple conditional queues can be associated Associate a conditional queue
reentrancy reentrant reentrant