The underlying implementation principle of ReentrantLock-Interview Guide

ReentrantLock is a reentrant mutex provided in Java, which has similar functions to the synchronized keyword, but is more flexible and controllable. The following is a brief explanation of the underlying implementation principle of ReentrantLock: The underlying implementation of ReentrantLock mainly depends on the AbstractQueuedSynchronizer (AQS) class. AQS is a framework for building locks and other synchronizers, which provides a synchronization mechanism based on FIFO waiting queues. ReentrantLock implements two modes of fair lock and unfair lock through AQS. In fair lock mode, threads acquire locks in the order in which they apply for locks; while in unfair lock mode, threads can acquire locks by preemption without guaranteeing the order. When a thread wants to acquire a lock, it will first try to modify the status value of AQS through the CAS (Compare and Swap) operation, and set the status of the lock to 1, indicating that the thread has acquired the lock. If the CAS operation fails, it means that other threads have acquired the lock, and the current thread will enter the waiting state. When a thread releases the lock, it calls the release method of AQS to release the lock resource. The process of releasing the lock mainly includes setting the state of the lock to 0, waking up the next thread in the waiting queue, and removing it from the waiting queue. ReentrantLock also supports reentrant features, that is, the same thread can acquire the same lock multiple times without causing deadlock. ReentrantLock internally maintains a counter that records the number of times the current thread acquires the lock. Only when the counter is 0, other threads can acquire the lock. In summary, the underlying implementation of ReentrantLock provides a synchronization mechanism based on FIFO waiting queues through the AQS class, and controls the acquisition and release of locks through CAS operations. At the same time, it also supports fair lock and unfair lock modes, and has reentrant features. These features make ReentrantLock more flexible and controllable to perform synchronization operations in a multi-threaded environment.

Here is a sample code using ReentrantLock:

javaCopy codeimport java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockExample {
    private static final ReentrantLock lock = new ReentrantLock();
    public static void main(String[] args) {
        Thread thread1 = new Thread(new Worker());
        Thread thread2 = new Thread(new Worker());
        thread1.start();
        thread2.start();
    }
    static class Worker implements Runnable {
        @Override
        public void run() {
            lock.lock(); // 获取锁
            try {
                // 执行需要同步的操作
                System.out.println("线程" + Thread.currentThread().getId() + "正在执行任务");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock(); // 释放锁
                System.out.println("线程" + Thread.currentThread().getId() + "释放了锁");
            }
        }
    }
}

In the above code, a static ReentrantLock object is used as a lock. In the run method of the Worker class, first use to ​lock.lock()​acquire the lock, then perform operations that require synchronization, and finally use to ​lock.unlock()​release the lock. Both threads will perform the same task, but because of the use of ReentrantLock, only one thread can acquire the lock, and the other thread will wait ​lock.lock()​at until the first thread releases the lock to continue the task. This can ensure that only one thread is executing tasks at the same time, and realizes mutual exclusion between threads. At the same time, because ReentrantLock is reentrant, the same thread can acquire the same lock multiple times without causing deadlock.

Guess you like

Origin blog.csdn.net/q7w8e9r4/article/details/132533830