当前位置:网站首页>In depth understanding of condition source code interpretation and analysis of concurrent programming
In depth understanding of condition source code interpretation and analysis of concurrent programming
2022-07-01 05:25:00 【Jackli1123 (cross correlation second return)】
Deep understanding of concurrent programming Condition Source code analysis
List of articles
One 、Condition What is it?
Condition It's an interface , It provides two core methods ,await() and signal() Method , amount to Object Of wait and notify Method , perform await() Method to enter the waiting state of the thread will be placed in Condition In the single queue of . Note that both the wait and wake methods need to be executed between the code blocks of the lock .
- firstWaiter:Condition The first person in the queue
- lastWaiter:Condition The last person in the queue
- await(): The current thread is waiting
- signal(): Wake up a waiting thread
- signalAll(): Wake up all waiting threads
Two 、Condition Detailed analysis
1. Illustrate with examples Condition Usage of
public class Test {
private static Lock lock = new ReentrantLock();
private static Condition condition = lock.newCondition();
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
lock.lock();
try {
System.out.println(Thread.currentThread().getName() + " Thread gets lock ");
condition.await();
System.out.println(Thread.currentThread().getName() + " End of thread execution ");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread.start();
try {
Thread.sleep(3000);
} catch (Exception e) {
}
lock.lock();
condition.signal(); // Wakes up the waiting thread , Wakes up but does not execute , Because the lock tag is now held by the main thread
System.out.println(Thread.currentThread().getName() + " End of main thread execution ");
lock.unlock(); //lock The lock needs to be released , Threads 0 Only when the lock tag is obtained can it be executed
}
}
Take a look at the execution results , At the beginning, the thread executes printing and obtains the lock , Yes await() Method entry wait , sleep 3 Seconds passed , The main thread acquires the lock ( Because the lock mark will be released after entering the blocking state ), When the main thread is finished , Release the lock and the sub thread continues to execute from the waiting place , It should be noted here that the main thread will always be locked if it does not release the lock mark Blocked state , Because the lock mark is not found at all :
1.Condition Source code analysis
await()
Have a look first condition Waiting method source code
public final void await() throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
Node node = addConditionWaiter(); //Condition Add a waiting person to the waiting queue
int savedState = fullyRelease(node);
int interruptMode = 0;
while (!isOnSyncQueue(node)) {
// If the current thread's waitStatus Status as -2 Wait state , Then execute the loop . The state of the node creating the waiting queue must be -2
LockSupport.park(this); // Blocking the current thread
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) // The corresponding interrupt jumps out of the loop
break;
}
//acquireQueued in front Lock Also talked about , Is to perform lock() Method , Inside first CAS Try to acquire the lock. If the lock cannot be acquired, it will enter the blocking state . When multiple threads wake up at the same time, they will enter lock Blocked state , Here's the original state The status has been modified
if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
interruptMode = REINTERRUPT;
if (node.nextWaiter != null) // There is no next waiting person to clear
unlinkCancelledWaiters();
if (interruptMode != 0)
reportInterruptAfterWait(interruptMode);
}
/** 1. Add the method of waiting */
private Node addConditionWaiter() {
Node t = lastWaiter; // First time in t It's empty
if (t != null && t.waitStatus != Node.CONDITION) {
// If the last node is not empty and the state is not waiting, clean up the threads in the blocking queue that are not waiting
unlinkCancelledWaiters();
t = lastWaiter;
}
// Create a node of the current thread and hang it at the back of the waiting queue
Node node = new Node(Thread.currentThread(), Node.CONDITION);
if (t == null)
firstWaiter = node;
else
t.nextWaiter = node; // You can see from here that , Only next But not pred explain Condition The queue of is one-way
lastWaiter = node;
return node; // Returns the node of the current thread
}
/** 2. Try to release the lock mark of the current thread and return to the original state , because lock The lock is reentrant , therefore state The value of is uncertain */
final int fullyRelease(Node node) {
boolean failed = true;
try {
int savedState = getState(); // Get the original state state
if (release(savedState)) {
// The current thread is unlocked , This is in Lock Of unlock() The method has already been discussed
failed = false;
return savedState;
} else {
throw new IllegalMonitorStateException();
}
} finally {
if (failed)
node.waitStatus = Node.CANCELLED;
}
}
/** 3. Will wait for the current wait -2 The status node is modified to 0 Waiting for lock status */
final boolean transferAfterCancelledWait(Node node) {
if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) {
// At this time, the modification status is changed by -2 Turned into 0, Waiting becomes blocked
enq(node); // Here, the current node is added to the blocking queue
return true;
}
while (!isOnSyncQueue(node))
Thread.yield();
return false;
}
Sum up await() Steps for :
- stay Condition Add the current thread as one of the waiters
- Try to make the current thread release the lock mark and record the current thread's state
- Change the status of the current thread node to -2 Wait state , Then block the current thread until the interrupt response obtains the lock mark and is awakened
- The interrupt response jumps out of the loop , Will thread the state state ( Number of re-entry locks ) Change to the original state .
signal()
Have a look first condition Wake up method source code :
/** 1. Wake up the first one waiting */
public final void signal() {
if (!isHeldExclusively())
throw new IllegalMonitorStateException();
Node first = firstWaiter;
if (first != null)
doSignal(first);
}
/** 2. Wake up the first one waiting */
private void doSignal(Node first) {
do {
if ( (firstWaiter = first.nextWaiter) == null) // It is judged here that if the first node is the next node of the first , Then there is a waiting , Empty
lastWaiter = null;
first.nextWaiter = null;
} while (!transferForSignal(first) &&
(first = firstWaiter) != null);
}
/** 3. Set the current thread to 0 Blocked state , And join the last node in the blocking queue */
final boolean transferForSignal(Node node) {
if (!compareAndSetWaitStatus(node, Node.CONDITION, 0)) // Change the status from -2 Turn into 0, Waiting becomes blocked
return false;
Node p = enq(node); // Set the current node as the last node in the blocking queue
int ws = p.waitStatus;
// If the node state >0, Just see if the lock tag is held by the current thread , Is to discard the lock tag , Generally, it will not wait for the thread to hold the lock mark
if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))
LockSupport.unpark(node.thread);
return true;
}
The method of awakening is relatively simple , Briefly describe what you did
- Change the state of the first node from -2 The waiting status is changed to 0 Blocked state
- Add this node to the blocking queue , Just wait to get the lock mark
Let's take a look at the following diagram to assume T1,T2,T3 How the three threads execute , hypothesis t2 Wait first , then t3 The wait method is executed again , Yes in the waiting pool t2 and t3, At this point, it wakes up t2, be t2 Entered the blocking queue , It is not directly implemented , Because I just wake up and haven't got the lock mark yet .
Content sources : Ant class
边栏推荐
- Unity项目心得总结
- C WPF uses dockpanel to realize screenshot box
- Explanation of characteristics of hydraulic slip ring
- AcWing 888. Finding combinatorial number IV (the problem of finding combinatorial number with high precision)
- Intelligent operation and maintenance: visual management system based on BIM Technology
- Actual combat: basic use of Redux
- AcWing 885. Find the combination number I (recursive preprocessing)
- Worried about infringement? Must share copyrightless materials on the website. Don't worry about the lack of materials for video clips
- One click deployment of highly available emqx clusters in rainbow
- Global and Chinese market of paper machine systems 2022-2028: Research Report on technology, participants, trends, market size and share
猜你喜欢

第05天-文件操作函数

Daily question -leetcode1175- permutation of prime numbers - Mathematics

Go learning notes (5) basic types and declarations (4)

El cascade echo failed; El cascader does not echo

Implementation of distributed lock

轻松上手Fluentd,结合 Rainbond 插件市场,日志收集更快捷

Software intelligence: the "world" and "boundary" of AI sentient beings in AAAs system

Understand several related problems in JVM - JVM memory layout, class loading mechanism, garbage collection

LevelDB源码分析之LRU Cache
![Is there any good website or software for learning programming? [introduction to programming]?](/img/ae/68a5880f313c307880ac80bd200530.jpg)
Is there any good website or software for learning programming? [introduction to programming]?
随机推荐
如何开始学剪辑?零基础详细解析
Lock free concurrency of JUC (leguan lock)
Tar command
What can the points mall Games bring to businesses? How to build a points mall?
Data consistency between redis and database
eBPF Cilium实战(2) - 底层网络可观测性
AcWing 884. Gauss elimination for solving XOR linear equations
AcWing 889. 01 sequence satisfying the condition (Cartland number)
One click deployment of highly available emqx clusters in rainbow
Tcp/ip explanation (version 2) notes / 3 link layer / 3.2 Ethernet and IEEE 802 lan/man standards
Thread safety issues
el-cascader回显失败;el-cascader回显不出来
Precautions for use of conductive slip ring
Practice of combining rook CEPH and rainbow, a cloud native storage solution
Day 05 - file operation function
[NLP Li Hongyi] notes
Global and Chinese markets of gps/gnss receiver modules 2022-2028: Research Report on technology, participants, trends, market size and share
智慧运维:基于 BIM 技术的可视化管理系统
Redis数据库的部署及常用命令
Rainbow combines neuvector to practice container safety management