当前位置:网站首页>Nucleic acid detection: let me understand the principle of AQS

Nucleic acid detection: let me understand the principle of AQS

2021-01-24 02:14:37 itread01

The Spring Festival is getting closer , The epidemic is getting worse and worse , But I can't stop calling lian to bring his family back home ( hubei ) The urge to reunite . Respond to the country's request to do ** nucleic acid test ** 了 .![image.png](https://cdn.nlark.com/yuque/0/2021/png/1897706/1611306766342-6abb6877-c070-44f0-b609-619b98618abf.png#align=left&display=inline&height=347&margin=%5Bobject%20Object%5D&name=image.png&originHeight=347&originWidth=505&size=63717&status=done&style=none&width=505)## Exclusive lock --- In the morning, Jiaolian took a family of three to Nanjing First Hospital for nucleic acid testing , The little sister of the nurse stood at the gate of the hospital and told us that there were more people , Both adults and children , We need to wait in line for doctors to collect saliva for testing ,OK, Now let's use code + Let's see how the three members of our family line up !```javaimport java.util.concurrent.locks.ReentrantReadWriteLock;/** * @author :jiaolian * @date :Created in 2021-01-22 10:33 * @description: Exclusive lock test * @modified By: * Public number : Call practice */public class ExclusiveLockTest { private static ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); private static ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock(); // Hospital private static class Hospital { private String name; public Hospital(String name) { this.name = name; } // Nucleic acid testing, queuing testing public void checkUp() { try { writeLock.lock(); System.out.println(Thread.currentThread().getName()+" We're doing nucleic acid testing "); // Nucleic acid process ... Uncomfortable ... Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } finally { writeLock.unlock(); } } } public static void main(String[] args) throws InterruptedException { Hospital hospital = new Hospital(" Nanjing First Hospital "); Thread JLWife = new Thread(()->hospital.checkUp()," It's called wife training "); JLWife.start(); // sleep 100 Millisecond is to let the three members of a family queue up in order to detect Thread.sleep(100); Thread JLSon = new Thread(()->hospital.checkUp()," It's called Lianzi "); JLSon.start(); Thread.sleep(100); Thread JL = new Thread(()->hospital.checkUp()," Call practice "); JL.start(); }}``` Code above : Start three threads in the main thread to line up at the hospital gate ,** Ladies first **, Wife training is at the top of the list , In the middle is the child called Lian , Finally, it's called practicing yourself . Let's assume that the next nucleic acid test needs 3 second . We use exclusive locks in our code , Exclusive lock can be understood as a hospital with only one doctor , A doctor can only do nucleic acid for one person at the same time , So we need to queue up one by one to detect , So it takes a total of 9 second , Nucleic acid testing can be done . The code logic is still relatively simple , And what we described in our previous article synchronized Empathy . Let's describe it with a graph !![image.png](https://cdn.nlark.com/yuque/0/2021/png/1897706/1611284683327-328575c1-1adc-40f3-9b99-813456f3fcc5.png#align=left&display=inline&height=407&margin=%5Bobject%20Object%5D&name=image.png&originHeight=407&originWidth=957&size=67154&status=done&style=none&width=957)AQS The full name is **AbstractQueueSynchroniz, Queue synchronizer **, It's essentially a two-way concatenation , stay AQS Each thread in it is encapsulated as a Node Node , Each node is added by tail insertion . In addition, nodes also encapsulate state information , For example, exclusive or shared , For example, the above case means exclusive Node, The doctor himself is a shared resource , stay AQS Inside, it's called state, use int Type means , All threads go through CAS In the same way state. The thread has got the lock , It's self increasing , Threads that don't grab the lock block and wait for the time to wake up . Here's the picture : Abstract according to our understanding AQS The internal structure of .![image.png](https://cdn.nlark.com/yuque/0/2021/png/1897706/1611286004499-547b1ef4-8bec-48c4-b1ff-88ce2041e136.png#align=left&display=inline&height=424&margin=%5Bobject%20Object%5D&name=image.png&originHeight=424&originWidth=983&size=77571&status=done&style=none&width=983)** According to the description above , Everyone to see AQS No, it does Node Encapsulating threads , Then follow the thread first come first served (**** Except for unfair lock ****) It's a two-way connected string ! About unfair lock I wrote before 《 Line up for dinner 》 The case is also described by simple examples . If you are interested in children's shoes, you can have a look !****## Shared lock --- The above process of making nucleic acid is executed synchronously , It's called exclusive lock . What does shared lock mean ? Now the only way to train children is 3 Year old , We can't do nucleic acid detection independently , Miss nurse, I feel the same , It is observed that jiaolianzi is behind jiaolianwife , Let them do nucleic acid tests at the same time . This kind of simultaneous manipulation of nucleic acids , It's equivalent to getting medical resources at the same time , We call it a shared lock . Here's our test code .```javaimport java.util.concurrent.locks.ReentrantReadWriteLock;/** * @author :jiaolian * @date :Created in 2021-01-21 19:54 * @description: Shared lock test * @modified By: * Public number : Call practice */public class SharedLockTest { private static ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); private static ReentrantReadWriteLock.ReadLock readLock = lock.readLock(); // Hospital private static class Hospital { private String name; public Hospital(String name) { this.name = name; } // Nucleic acid testing, queuing testing public void checkUp() { try { readLock.lock(); System.out.println(Thread.currentThread().getName()+" We're doing nucleic acid testing "); // Nucleic acid process ... Uncomfortable ... Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } finally { readLock.unlock(); } } } public static void main(String[] args) throws InterruptedException { Hospital hospital = new Hospital(" Nanjing First Hospital "); Thread JLWife = new Thread(()->hospital.checkUp()," It's called wife training "); JLWife.start(); // sleep 100 Millisecond is to let the three members of a family queue up in order to detect Thread.sleep(100); Thread JLSon = new Thread(()->hospital.checkUp()," It's called Lianzi "); JLSon.start(); /*Thread.sleep(100); Thread JL = new Thread(()->hospital.checkUp()," Call practice "); JL.start();*/ } }``` The above code we use ReentrantReadWriteLock.ReadLock As a read lock , Start in the main thread “ It's called wife training ” and “ Call practice ” Two threads , Originally, mother and son needed 6 What can be done in seconds , Now all I need is 3 It can be done in seconds , The advantage of shared lock is high efficiency . Here's the picture , yes AQS At some point inside Node Node status . Compare the picture above ,**Node The state of is changed to shared state , These nodes can share doctor resources at the same time **!![image.png](https://cdn.nlark.com/yuque/0/2021/png/1897706/1611298738189-d5f9e42b-820b-454a-8cce-40b29fccb9fe.png#align=left&display=inline&height=433&margin=%5Bobject%20Object%5D&name=image.png&originHeight=433&originWidth=882&size=67291&status=done&style=none&width=882)## synchronized Lock does not respond to interrupt ---```java/** * @author :jiaolian * @date :Created in 2020-12-31 18:17 * @description:sync Do not respond to interrupt * @modified By: * Public number : Call practice */public class SynchronizedInterrputedTest { private static class MyService { public synchronized void lockInterrupt() { try { System.out.println(Thread.currentThread().getName()+" Got the lock "); while (true) { //System.out.println(); } } catch (Exception e) { e.printStackTrace(); } } } public static void main(String[] args) throws InterruptedException { MyService myService = new MyService(); // Start thread first A, Let the thread A Have the lock first Thread threadA = new Thread(()->{ myService.lockInterrupt(); }); threadA.start(); Thread.sleep(1000); // Start the thread B, Interruption ,synchronized Do not respond to interrupt ! Thread threadB = new Thread(()->{ myService.lockInterrupt(); }); threadB.start(); Thread.sleep(1000); threadB.interrupt(); }}``` Code like above : Start first A Thread , Let the thread A Have the lock first , sleep 1 Second to start the thread B It's Jean B The thread is in an executable state , Partition 1 Interrupt in seconds B Thread . The output on the console is as follows :A The thread has acquired the lock , wait for 2 Seconds later, the console did not immediately output error information , The program has not finished running , Explain **synchronized Lock does not respond to interrupt , need B After the thread acquires the lock, it will output the thread interrupt error information !**![image.png](https://cdn.nlark.com/yuque/0/2021/png/1897706/1611299701736-370a64d7-c079-4ed1-91ab-3b73eab0b64a.png#align=left&display=inline&height=220&margin=%5Bobject%20Object%5D&name=image.png&originHeight=220&originWidth=548&size=13708&status=done&style=none&width=548)## AQS Response interrupted --- Often do comparison, knowledge will be integrated , stay Lock Provide lock and lockInterruptibly Two ways to get locks , among lock Methods and **synchronized** It doesn't respond to interrupts , Let's take a look **lockInterruptibly** What does response interrupt mean . Let's use nucleic acid as an example .```javaimport java.util.concurrent.locks.ReentrantReadWriteLock;/** * @author :jiaolian * @date :Created in 2021-01-22 15:18 * @description:AQS Response interrupt code test * @modified By: * Public number : Call practice */public class AQSInterrputedTest { private static ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); private static ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock(); // Hospital private static class Hospital { private String name; public Hospital(String name) { this.name = name; } // Nucleic acid testing, queuing testing public void checkUp() { try { writeLock.lockInterruptibly(); System.out.println(Thread.currentThread().getName()+" We're doing nucleic acid testing "); // Nucleic acid process ... Uncomfortable ... Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } finally { writeLock.unlock(); } } } public static void main(String[] args) throws InterruptedException { Hospital hospital = new Hospital(" Nanjing First Hospital "); Thread JLWife = new Thread(()->hospital.checkUp()," It's called wife training "); JLWife.start(); // sleep 100 Millisecond is to let the three members of a family queue up in order to detect Thread.sleep(100); Thread JLSon = new Thread(()->hospital.checkUp()," It's called Lianzi "); JLSon.start(); Thread.sleep(100); Thread JL = new Thread(()->hospital.checkUp()," Call practice "); JL.start(); // wait for 1 second , Interruption is called thread training System.out.println(" Miss nurse wants to have a private chat with Jiaolian !"); Thread.sleep(1000); JL.interrupt(); }}``` Code above : The three members of the Jiaolian family use exclusive locks to queue up for nucleic acids , Ask the thread to wait for one second , Miss nurse wants to have a private chat with Jiaolian ! What would my little sister think , So call practice immediately interrupted the nucleic acid detection , Note that ** Immediately interrupt **. The results of printing on the console are as follows : Call to practice wife thread and call to practice son thread are done , But Jiaolian failed ! Because it was interrupted by the nurse's little sister , The results are shown in the figure below . So we can come to the conclusion that , stay aqs The middle lock can respond to interrupt . Now if you put the above code in lockInterruptibly Change the method to lock What happens to the method , If it's this way , Little sister, please tease me again , Call practice to get the lock first , That is to say, Jiaolian has come to the doctor to prepare for nucleic acid therapy , My little sister suddenly said she had something to ask for ,** In the end, Jiaolian didn't do it **, When things like this happen , It can only be said that the little sister is intentional , Cute girl ** Too bad ** 了 . About lock Method does not respond to interrupt test, you can test under their own . See if I'm ** wronged ** The nurse's little sister . We can come to the conclusion that : stay aqs If a thread is acquiring a lock or in a wait state , Another thread interrupts that thread , Response interrupt means that the thread immediately interrupts , Not responding to an interrupt means that the thread needs to acquire a lock before it interrupts .![image.png](https://cdn.nlark.com/yuque/0/2021/png/1897706/1611302174719-33066e7c-c789-4fba-b539-c54a622dfdbb.png#align=left&display=inline&height=291&margin=%5Bobject%20Object%5D&name=image.png&originHeight=291&originWidth=944&size=53011&status=done&style=none&width=944)![image.png](https://cdn.nlark.com/yuque/0/2021/png/1897706/1611302781019-8f417560-8249-4c17-8b31-4bbbece0f020.png#align=left&display=inline&height=473&margin=%5Bobject%20Object%5D&name=image.png&originHeight=473&originWidth=968&size=88503&status=done&style=none&width=968)## Condition queue --- There may be some disappointments in life . The long hour of waiting in line finally passed , It's our turn to prepare for nucleic acid , You said ** Not angry **, Every time I ask my wife to go out, I bring my ID card , But I forgot to go home this time ? Let's use the code to see what happened in the process of making nucleic acid ? How to deal with it !```javaimport java.util.concurrent.locks.Condition;import java.util.concurrent.locks.ReentrantReadWriteLock;/** * @author :jiaolian * @date :Created in 2021-01-22 16:10 * @description: Conditional queue test * @modified By: * Public number : Call practice */public class ConditionTest { private static ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); private static ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock(); // Condition queue private static Condition condition = writeLock.newCondition(); // Hospital private static class Hospital { private String name; public Hospital(String name) { this.name = name; } // Nucleic acid testing, queuing testing public void checkUp(boolean isIdCard) { try { writeLock.lock(); validateIdCard(isIdCard); System.out.println(Thread.currentThread().getName()+" We're doing nucleic acid testing "); // Nucleic acid process ... Uncomfortable ... Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } finally { writeLock.unlock(); System.out.println(Thread.currentThread().getName()+" Nucleic acid testing is complete "); } } // Verify identity information ; private void validateIdCard(boolean isIdCard) { // If there is no identity information , Need to wait if (!isIdCard) { try { System.out.println(Thread.currentThread().getName()+" I forgot to bring my ID card "); condition.await(); } catch (InterruptedException e) { e.printStackTrace(); } } } // Inform all who are waiting public void singleAll() { try { writeLock.lock(); condition.signalAll(); } catch (Exception e) { e.printStackTrace(); } finally { writeLock.unlock(); } } } public static void main(String[] args) throws InterruptedException { Hospital hospital = new Hospital(" Nanjing First Hospital "); Thread.currentThread().setName(" The nurse's little sister's thread "); Thread JLWife = new Thread(()->{ hospital.checkUp(false); }," It's called wife training "); JLWife.start(); // sleep 100 Millisecond is to let the three members of a family queue up in order to detect Thread.sleep(100); Thread JLSon = new Thread(()->hospital.checkUp(true)," It's called Lianzi "); JLSon.start(); Thread.sleep(100); Thread JL = new Thread(()->{ hospital.checkUp(true); }," Call practice "); JL.start(); // Wait for the call thread to finish JL.join(); hospital.singleAll(); }}``` Code above : A family needs to queue up to get the exclusive lock , Ask Lian wife to prepare nucleic acid first , The little sister of the nurse said she had to brush her ID card before she could go in , Call practice wife suddenly recall , I forgot my ID card when I was in a hurry , How to do that , Need to queue up again ? It's scary to call wife training , The nurse said , How about this , You go home and get it , Wait for Lianzi , Let's finish the test first , I'll arrange for you to go in and do the nucleic acid , So you don't have to queue up again , That's what the code says . Let's take a look at the execution results, as shown in the figure below , Consistent with our analysis , The place with the red circle at the end of the picture below is called practice wife, and finally complete the nucleic acid test . Let's take a look at AQS The process of internal experience .![image.png](https://cdn.nlark.com/yuque/0/2021/png/1897706/1611304655228-aad9da15-45d4-42e8-b683-f915a15a2173.png#align=left&display=inline&height=274&margin=%5Bobject%20Object%5D&name=image.png&originHeight=274&originWidth=593&size=21325&status=done&style=none&width=593) Here's the picture , When you ask your wife to get the lock first , I found that I forgot to bring my ID card **await** Method releases the lock held , And think of yourself as node The node is placed at the end of the conditional queue , The condition queue is empty , So there is only one thread called Wife Training in the condition queue , Then the nurse will release the resource of nucleic acid doctor to the next waiting person , That is to say, it's called practicing the thread of execution , Empathy , After the completion of the call queue, releasing the lock will wake up the call queue thread , The bottom layer is LockSupport.unpark To complete the wake-up operation , It's equivalent to wait/notify/notifyAll Other methods . When the call train thread is finished , There's no thread in the back , The nurse's little sister called singleAll Method to wake up the wife training thread in the meeting condition queue , And join in AQS Tail of , Waiting for execution . The conditional queue is a one-way connection string , One AQS It can be done by newCondition() Corresponding to multiple condition queues . Here we don't test with code alone .![image.png](https://cdn.nlark.com/yuque/0/2021/png/1897706/1611305244792-22389c84-15a8-4f1b-9cb4-39f978e92dad.png#align=left&display=inline&height=600&margin=%5Bobject%20Object%5D&name=image.png&originHeight=600&originWidth=753&size=60995&status=done&style=none&width=753)## Summary --- Today we use code + Pictures + The way of the story illustrates AQS Important concepts , I hope it will help you , I can't write it completely , At the same time, there are many things that need to be corrected , I hope you can correct me and comment on it , Years ago this time will continue to output to achieve AQS High order locks , Such as :ReentrantLock, Thread pool, these concepts, etc . Finally, please pay attention to those you like . I am a ** Call practice 【 Public number 】**, Call and practice .** Be careful : This story is made up by myself , For your reference only . I hope everyone can go home and get together during the new year !****![tempImage1611306633088.gif](https://cdn.nlark.com/yuque/0/2021/gif/1897706/1611306713183-cc11c946-1455-4f12-a60e-6e84fa3d65be.gif#align=left&display=inline&height=128&margin=%5Bobject%20Object%5D&name=tempImage1611306633088.gif&originHeight=128&originWidth=128&size=20544&status=done&style=none&width

版权声明
本文为[itread01]所创,转载请带上原文链接,感谢
https://chowdera.com/2021/01/20210124021048229n.html

随机推荐