当前位置:网站首页>Analysis of the semaphore source code of AQS
Analysis of the semaphore source code of AQS
2022-07-28 06:45:00 【yfyh2021】
- about semaphore Where is the focus of the source code
- semaphore The logical implementation of locking and unlocking .
- The thread that obtains the lock releases the lock and wakes up the logic that the blocking thread competes for the lock .
- Code preparation
public class SemaphoreTest1 {
public static void main(String[] args) {
Semaphore windows = new Semaphore(3);
for(int i=0;i<5;i++){
new Thread(()->{
try {
windows.acquire();
System.out.println(Thread.currentThread().getName()+": Start buying tickets ");
Thread.sleep(5000);
System.out.println(Thread.currentThread().getName()+": Successful ticket purchase ");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
windows.release();
}
}).start();
}
}
}A simple simulation of ticket buying logic . We still follow the analysis reentrantlock Of debug Way to analyze code .
- debug Execution process

We should first control thread0 Enter and lock acquire() Method , Incoming arg Parameter is 1, Get into tryAcquireShared(arg) Method

Get into nonfairTryAcquireShared(int acquires) Method , here ,AQS In the control state state Attributes are what we create semaphore Value initialized when ( In unshared locks , We know AQS Of state by 0 You need to block threads ), Finally back to remaining by 2.

In this case , We control the first three threads to enter the lock code block in turn, and all of them are unobstructed , Until our fourth thread thread3.
stay nonfairTryAcquireShared(int acquires) In the method ,remaining by -1, hinder cas The operation will not be performed ,available keep 0. Return results -1. In this case acquireSharedInterruptibly() Method to enter the second if The logical execution of judgment doAcquireSharedInterruptibly(arg) Method .

We can see that the structure of this method is very familiar , and reentraintlock Very similar : addWaiter(Node.SHARED) The method is to build a linked list and join the team ; And then a for loop ;for In the loop, first get the previous node method of the current node node.predecessor(); Then enter a lock acquisition attempt ; then if The logic of is part of the content of the team ; Finally, change node node waitStatus Attribute shouldParkAfterFailedAcquire() Methods and blocking threads parkAndCheckInterrupt() Method .

In team formation and team entry methods addWaiter The middle is AQS Common method , and reentrantlock There are more nodes than ours nextWaiter attribute , The function of this attribute will be mentioned later .

In an attempt to acquire a lock , here state by 0, So back remaining by -1, So skip the first if Judgment logic , We enter shouldParkAfterFailedAcquire Method .

You can see that this method is AQS Sharing method , and reentrantlock Agreement , It is also the head node waitStatus Attribute from 0 Change it to SINGNAL(-1) , Finally, it will cycle into the blocking method again .

Let's control our thread0 To release the lock .

We can see tryReleaseShared() The way is to lock us state adopt cas Operation by 0 Turn into 1.

stay doReleaseShared() In the method , Will be the head node of waitStatus State again -1 Change it to 0, Then enter unparkSuccessor(h) Method wake up thread .

thread3 Awakened ,remaining return 0, Get into if In judgment , perform setHeadAndPropagate() Method

setHead() The method is half out , Cooperate with the subsequent method of the cycle in which the blocking queue method is located to realize the node out of the queue . Pay attention to the following about propagate A series of operations about whether to spread . We know that we are building SHARED Attribute node Node time , We added nextWaiter attribute , Through this attribute, we enter doReleaseShared() In the method .

Now our head The node is originally bound thread3 The node of , Enter the wake-up method unparkSuccessor(h)

We will find that we will wake up thread3 The next node of the node , So every time you get a lock , All blocked threads with shared nodes will be awakened once , If the subsequent nodes pred It happens that the head node will try to acquire the lock , Increase of efficiency .
So for shared locks , As long as the number of resources is sufficient , You can always wake up .
边栏推荐
猜你喜欢

[PTA--利用队列解决猴子选大王问题】

2022-05-24 use of spiel

Leetcode brush question diary sword finger offer II 055. binary search tree iterator

项目编译NoSuch***Error问题

What is hash? (development of Quantitative Trading Robot System)

About the collation of shader keyword

STM32的IAP跳转相关bug经历

mongoDB复制集及分片集群

【动态规划--买卖股票的最佳时期系列】

Two dimensional array practice: spiral matrix
随机推荐
Personal understanding of Chinese remainder theorem
What's a good gift for your girlfriend on Chinese Valentine's day? Boys who can't give gifts, look!
[dynamic planning -- the best period for buying and selling stocks Series 2]
[c语言]简易通讯录的实现
OJ 1253 ordering problem
Everything you don't know about time complexity is here
mongoDB快速入门
Leetcode 刷题日记 剑指 Offer II 053. 二叉搜索树中的中序后继
OJ 1020 minimum palindromes
OJ 1018 counting game
【C笔记】数据类型及存储
雨伞上的水滴效果
[pta-- use queues to solve the problem of monkeys choosing kings]
New Selenium
浮点型数据在内存中如何存储
刷题记录----反转链表(反转整个链表)
关于Shader KeyWord的整理
结构体、位段、联合体(共用体)的大小如何计算
[C note] data type and storage
【动态规划--买卖股票的最佳时期系列】