In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
Editor to share with you how to achieve AQS in JAVA, I believe that most people do not know much about it, so share this article for your reference, I hope you can learn a lot after reading this article, let's go to know it!
AbstractQueuedSynchronizer is the core framework of JUC and its design is very exquisite. The template method mode of Java is used. First, try to restore its usage scenario:
For exclusive locks, only one thread of N threads can acquire the lock at the same time; the other threads that did not acquire the lock are suspended and placed in the queue, and the thread in the queue is awakened after the thread that acquired the lock releases the lock.
The thread hangs by calling the Unsafe.park () method when it fails to acquire the lock; the thread wakes up by calling Unsafe.unpark () when another thread releases the lock.
Since it may only take a few milliseconds to acquire the lock, execute the in-lock code logic, and release the lock, it is difficult to have an intuitive sense of lock contention. Here is a simple simulation of the exclusive lock mechanism with three threads.
Import sun.misc.Unsafe;import java.lang.reflect.Field;import java.util.ArrayList;import java.util.List;import java.util.concurrent.locks.LockSupport;public class AQSDemo {private static final Unsafe unsafe = getUnsafe (); private static final long stateOffset; private static Unsafe getUnsafe () {try {Field field = Unsafe.class.getDeclaredField ("theUnsafe"); field.setAccessible (true); return (Unsafe) field.get (null) } catch (Exception e) {} return null;} static {try {stateOffset = unsafe.objectFieldOffset ("state"));} catch (Exception ex) {throw new Error (ex);}} private volatile int state; private List threads = new ArrayList () Public void lock () {if (! unsafe.compareAndSwapInt (state,stateOffset,0,1)) {/ / has a problem, which is not thread safe Use threads.add (Thread.currentThread ()); LockSupport.park (); Thread.interrupted ();}} public void unlock () {state = 0; if (! threads.isEmpty ()) {Thread first = threads.remove (0); LockSupport.unpark (first) for demonstration only }} static class MyThread extends Thread {private AQSDemo lock; public MyThread (AQSDemo lock) {this.lock = lock;} public void run () {try {lock.lock (); System.out.println ("run"); Thread.sleep (1000) } catch (InterruptedException e) {e.printStackTrace ();} finally {lock.unlock ();} public static void main (String [] args) {AQSDemo lock = new AQSDemo (); MyThread A1 = new MyThread (lock); MyThread a2 = new MyThread (lock); MyThread a3 = new MyThread (lock) A1.start (); a2.start (); a3.start ();}}
The above code, using park and unpark, simply simulates how an exclusive lock works. The use of ArrayList shields the construction details of linked lists in a multithreaded environment. It is actually a problem for this code to be used in a multithreaded environment. Have you found it?
Through the above code, we can understand why linked lists work better than ArrayList in a multithreaded environment.
The core of understanding AQS is to understand state, head and tail. In other words, to understand AQS, you only need to understand the state and the queue implemented by the linked list. The way to use it is to suspend the thread and throw it into the queue if the status update is not successful; when the other threads are finished, wake up a thread from the queue to execute. If there are too many threads in the queue, it is important to pay attention to who gets the lock first and cannot operate secretly, so there are fair and unfair strategies.
More and more able to understand "programming skills, details are the devil", to understand the use of the above, is only equivalent to understanding the requirements. So what are the details of the implementation? We clarify it through questions and answers.
Question1: why should state variables be modified with the volatile keyword?
Volatile is a lightweight version of synchronized that has lock characteristics in specific scenarios. The updated value of a variable does not depend on the current value, such as the setState () method. When the volatile scenario is not satisfied, you can use Unsafe.compareAndSwap.
Question 2: how does a linked list ensure a linked structure in a multithreaded environment?
First of all, we look at the linked list is a two-way linked list, we look at the linked list of several states:
1. Empty linked list (uninitialized) head-- nulltail-- null or (after initialization) head-- Empty Nodetail-- Empty Node2. A linked list of only one element head-- Empty Node Thread Node-- tail
That is, when the linked list is not empty, the filler in the linked list has a placeholder node.
Learn the data structure, understand the insert and delete operations, and basically understand the data structure. Let's first look at the insert operation enq ():
Private Node enq (final Node node) {for (;;) {Node t = tail; if (t = = null) {/ / Must initialize if (compareAndSetHead (new Node () tail = head;} else {node.prev = t If (compareAndSetTail (t, node)) {t.next = node; return t;}}
First of all, an infinite loop. If the linked list is not initialized, then the linked list will insert 2 nodes through the circular structure. Because there will be failures in compareAndSet in a multithreaded environment, the failure retry is guaranteed through a loop. To ensure synchronization, you either rely on locks or through CPU's cas. Here is the implementation synchronizer, which can only rely on cas. This kind of programming structure, watching AtomicInteger, will be very familiar.
Next, look at the delete operation of the linked list. When a thread releases the lock and calls the release () method, AQS wakes up a qualified thread in the order in which it enters the queue, which is the embodiment of FIFO. The code is as follows:
Public final boolean release (int arg) {if (tryRelease (arg)) {Node h = head; if (h! = null & & h.waitStatus! = 0) unparkSuccessor (h); return true;} return false;}
Let's ignore the waitStatus in unparkSuccessor () here. In this way, the thread continues to execute from behind the blocking and comes out of the parkAndCheckInterrupt () method.
Final boolean acquireQueued (final Node node, int arg) {boolean failed = true; try {boolean interrupted = false; for (;;) {final Node p = node.predecessor (); if (p = = head & & tryAcquire (arg)) {setHead (node); p.next = null / / help GC failed = false; return interrupted;} if (shouldParkAfterFailedAcquire (p, node) & & parkAndCheckInterrupt () interrupted = true;}} finally {if (failed) cancelAcquire (node);}}
Since the wake-up order is FIFO, the p==head condition is usually satisfied. If the lock is acquired, the current node is used as the head node of the linked list: setHead (node). The original head node is disconnected from the linked list, and the GC reclaims the p.next=null. In other words, the deletion of the linked list is deleted from scratch in order to achieve the goal of FIFO.
At this point, the linked list operation of AQS is clear.
These are all the contents of the article "how to achieve AQS in JAVA". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!
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.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.