It is said that AQS is not easy to understand, so let’s take a step forward today and talk about it

Hello everyone, 方圆
let us learn a lot of threads together!


1. Application of AQS in CountDownLatch

1.1 The AQS static inner class

Insert picture description here

protected access 基类中的protected成员是包内可见的,并且对子类可见Range: ;若子类与基类不在用一个包,那么子类可以访问从基类中继承来的protected方法,而不能访问基类的protected方法

1.2 Construction method

Insert picture description here
Insert picture description here
Insert picture description here

1.3 getCount() method

Insert picture description here
Insert picture description here
Insert picture description here

1.4 CountDown() method

Insert picture description here
However, this releaseShared method, Sync did not rewrite it, but调用其父类AbstractQueueSynchronizer中的方法
Insert picture description here
Insert picture description here
Insert picture description here

1.5 await() method

Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
The purpose of executing this method is to block the thread.
Insert picture description here
The blocking queue is as shown in the figure below. Push Node into the queue and block it. The parkAndCheckInterrupt()method is to achieve the blocking
Insert picture description here
Insert picture description here
.
Insert picture description here

1.6 Summary

  • When the await method of CountDownLatch is called, it will try to obtain a "shared lock", but it cannot be obtained at the beginning, so the thread is blocked
  • The "acquisition condition of a shared lock" is that the value of the counter is 0
  • The initial value of the counter is set by us, which corresponds to the state value. Only when the countDown() method is executed, the lock counter can be decremented by 1
  • Until the state threads execute countDown(), reduce it to 0, and the aforementioned threads waiting to acquire the shared lock can continue to run

2. Application of AQS in Semaphore

2.1 acquire() method

Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here

2.2 release() method

Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here

2.3 Summary

  • In Semaphore, state represents the remaining number of licenses
  • nonfairTryAcquireShared方法The return value is greater than 0, which means the semaphore is successfully obtained
  • If the return is a negative number, it means that there is no more semaphore that can be obtained again, and block

3. Application of AQS in ReentrantLock

3.1 lock() method

Insert picture description here
Enter the acquire method, indicating that the lock has been acquired, then in this acquire method, it must be judged 重入and 其他线程的阻塞
Insert picture description here
Insert picture description here
Insert picture description here
we will look back at the require method. The first condition has been judged to be completed. If it is the first two cases, then return true and negate Is false, no longer execute downward; if it is the last case, execute the following method
Insert picture description here

3.2 unlock() method

Insert picture description here
Enter the release method in the AQS parent class
Insert picture description here
Insert picture description here
Insert picture description here

3.3 Summary

  • state represents the number of reentrants. Each time the lock is released, first judge whether the current thread releases the lock. If not, report an error; otherwise, the number of reentrants is reduced by 1 until it reaches 0, which means it is completely released. Free is true, and Set state to 0

4. Implement an AQS yourself

Insert picture description here

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedLongSynchronizer;

//让我们做一个门栓,进来线程都进行等待,由主线程进行放开
public class MyCountDown {
    
    

    private Sync sync = new Sync();

    private static class Sync extends AbstractQueuedLongSynchronizer{
    
    

        @Override
        protected long tryAcquireShared(long arg) {
    
    
            //初始值为0,返回-1,那么将会被阻塞
            return (getState() == 1) ? 1 : -1;
        }

        @Override
        protected boolean tryReleaseShared(long arg) {
    
    
            //只要执行了signal方法,那么就直接将state设置为1
            //开闸放水
            setState(1);

            return true;
        }
    }

    public void signal() {
    
    
        //唤醒线程
        sync.releaseShared(0);
    }

    public void await() {
    
    
        //让线程进行等待
        sync.acquireShared(0);
    }

    public static void main(String[] args) throws InterruptedException {
    
    
        MyCountDown myCountDown = new MyCountDown();

        for (int i = 0; i < 3; i++) {
    
    
            new Thread(() -> {
    
    
                System.out.println(Thread.currentThread().getName() + "进入门内");
                myCountDown.await();
                System.out.println(Thread.currentThread().getName() + "开闸跑了");
            }).start();
        }

        TimeUnit.SECONDS.sleep(3);

        myCountDown.signal();
    }
}
  • Results of the
    Insert picture description here

5. Summary

Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here


Come on!

Guess you like

Origin blog.csdn.net/qq_46225886/article/details/107749212