Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to understand park wait and unpark Wake up in LockSupport Class

2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly explains "how to understand park waiting and unpark Wake up in LockSupport Class". The content in the article is simple and clear, and it is easy to learn and understand. please follow the editor's train of thought to study and learn "how to understand park waiting and unpark Wake up in LockSupport Class".

1. Traditional synchronized implicit lock package com.lau.javabase.lock.LockSupport;import java.util.concurrent.TimeUnit / * before using LockSupport, there are problems with traditional synchronized methods: * 1, wait () and notify () methods cannot be separated from the synchronous code block (lock). If the notify () method of * 2 and B thread is executed before the wait () of A thread, A thread will not be awakened * / public class BeforeUseTraditional {public static void main (String [] args) {Object lockObj = new Object () / / thread A new Thread (()-> {/ / try {/ / TimeUnit.SECONDS.sleep (3); / /} catch (InterruptedException e) {/ / e.printStackTrace () / /} / / synchronized (lockObj) {System.out.println (Thread.currentThread (). GetName () + "come in..."); try {lockObj.wait ();} catch (InterruptedException e) {e.printStackTrace () } System.out.println (Thread.currentThread (). GetName () + "awakened..."); / /}}, "A") .start (); / / try {/ / TimeUnit.SECONDS.sleep (3); / /} catch (InterruptedException e) {/ / e.printStackTrace () / / Thread B wakes up thread A new Thread (()-> {/ / synchronized (lockObj) {lockObj.notify (); System.out.println (Thread.currentThread (). GetName () + "notify..."); / /}}, "B") .start ();}}

Output:

A come in...Exception in thread "A" Exception in thread "B" java.lang.IllegalMonitorStateException at java.lang.Object.notify (Native Method) at com.lau.javabase.lock.LockSupport.BeforeUseTraditional.lambda$main$1 (BeforeUseTraditional.java:42) at java.lang.Thread.run (Thread.java:745) java.lang.IllegalMonitorStateException at java.lang.Object.wait (Native Method) at java.lang.Object.wait (Object.java:502 ) at com.lau.javabase.lock.LockSupport.BeforeUseTraditional.lambda$main$0 (BeforeUseTraditional.java:25) at java.lang.Thread.run (Thread.java:745) Process finished with exit code 0

Conclusion: the wait () and notify () methods cannot be used separately from the synchronous code block (lock).

2. ReentrantLock display lock package com.lau.javabase.lock.LockSupport;import java.util.concurrent.TimeUnit;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock / * the problem with Lock mode before using LockSupport: * 1, await () and signal () methods cannot be separated from the synchronous code block (lock). If the * 2, B thread and signal () methods are executed before the A thread's await (), the A thread will not be awakened * / public class BeforeUseLock {public static void main (String [] args) {Lock lock = new ReentrantLock () Condition condition = lock.newCondition (); / / Thread A new Thread (()-> {try {TimeUnit.SECONDS.sleep (3);} catch (InterruptedException e) {e.printStackTrace ();} try {lock.lock () System.out.println (Thread.currentThread (). GetName () + "come in..."); try {condition.await ();} catch (Exception e) {e.printStackTrace () } System.out.println (Thread.currentThread (). GetName () + "awakened...");} finally {lock.unlock ();}}, "A") .start (); / / try {/ / TimeUnit.SECONDS.sleep (3) / /} catch (InterruptedException e) {/ / e.printStackTrace (); / /} / / Thread B wakes up thread A new Thread (()-> {try {lock.lock (); condition.signal (); System.out.println (Thread.currentThread (). GetName () + "notify...") } finally {lock.unlock ();}}, "B") .start ();}}

Output:

B notify...A come in...

Conclusion: if the and signal () methods of thread B are executed before the await () of thread A, thread A will not be awakened.

Third, Locksupport class package com.lau.javabase.lock.LockSupport;import java.util.concurrent.TimeUnit;import java.util.concurrent.locks.LockSupport / * when using LockSupport, the following problems do not exist: * 1, await () and signal () methods cannot break away from the synchronous code block (lock) and use the * 2, B thread and signal () methods to execute before the A thread's await () alone. A thread will not be awakened * / public class LockSupportTest {public static void main (String [] args) {/ / Thread A Thread threadA = new Thread (()-> {try {TimeUnit.SECONDS.sleep (3)) } catch (InterruptedException e) {e.printStackTrace ();} System.out.println (Thread.currentThread (). GetName () + "come in..."); LockSupport.park (); System.out.println (Thread.currentThread (). GetName () + "awakened...");}, "A"); threadA.start () }, "B") .start ()

Output:

B notify...A come in...An awakened...

Conclusion: the above two problems do not exist when using LockSupport.

IV. Explanation

LockSupport is the basic thread blocking primitive used to create locks and other synchronization classes

LockSupport is a thread blocking utility class. All methods are static methods that allow threads to block anywhere, and there are corresponding wake-up methods after blocking. Return to the root

At the end, the native code in the Unsafe called by LockSupport.

LockSupport provides park () and unpark () methods to block and unblock threads.

LockSupport has a permit association with each thread that uses it. Permit is equivalent to the switch of 1 and 0, and the default is 0.

Call unpark once and add 1 to 1.

A call to park consumes permit, which turns 1 into o, and park returns immediately.

If you call park again, it will become blocked (because permit is zero, it will block here until permit becomes 1), and calling unpark will set permit to 1.

Each thread has an associated permit, and there is at most one permit, and repeated calls to unpark do not accumulate credentials.

The understanding of image

Thread blocking requires a consuming credential (permit), which is limited to one.

When the park method is called

* if there is a certificate, it will be consumed directly and then exit normally

* if there are no credentials, you must block and wait for the credentials to be available

Unpark, on the other hand, adds one credential, but there can only be one credential, which is not valid.

V. expansion

1. Why can I wake up the thread first and then block it?

Because unpark gets a credential and then calls the park method, you can justifiably consume the credential, so it doesn't block.

2. Why wake up twice and block twice, but end up blocking the thread?

Because the maximum number of credentials is 1, calling unpark twice in succession has the same effect as calling unpark once, and only one credential will be added.

Thank you for reading, the above is the content of "how to understand park waiting and unpark Wake up in LockSupport Class". After the study of this article, I believe you have a deeper understanding of how to understand park waiting and unpark Wake up in LockSupport class, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report