Java concurrent packet source code learning-AQS framework (2) CLH lock queue and spin lock, aqsclh

Source: Internet
Author: User
Tags lock queue

Java concurrent packet source code learning-AQS framework (2) CLH lock queue and spin lock, aqsclh

As mentioned in the previous article, AQS is based onCLH lock queueSo what is CLH lock queue? complexity is complicated, simple, and simple. The so-called greatest truths are simple:

CLH lock queue is actually a FIFO queue, and each node (thread) in the queue only needs to wait for its previous step to release the lock.

AbstractQueuedSynchronizerIs through an internal classNodeTo implement a variant of CLH lock queue, but the basic principle is similar.

In IntroductionNodeClass, let's introduceSpin LockGenerallyCLH lock queueTo implement the spin lock, the so-called spin lock is simply a thread waiting through a loop rather than sleep. Talk is much worse than show code:

Class ClhSpinLock {private final ThreadLocal <Node> prev; private final ThreadLocal <Node> node; private final AtomicReference <Node> tail = new AtomicReference <Node> (new Node ()); public ClhSpinLock () {this. node = new ThreadLocal <Node> () {protected Node initialValue () {return new Node () ;}}; this. prev = new ThreadLocal <Node> () {protected Node initialValue () {return null ;};} public void lock () {final Node node = this. node. get (); node. locked = true; // a CAS operation can add the node corresponding to the current thread to the queue, // and get the reference of the forward node at the same time, then, wait for the previous step to release the lock Node pred = this. tail. getAndSet (node); this. prev. set (pred); while (pred. locked) {// enter the spin} public void unlock () {final Node node = this. node. get (); node. locked = false; this. node. set (this. prev. get ();} private static class Node {private volatile boolean locked ;}}

In the above Code, the thread cleverly passesThreadLocalSaves the reference of the current node and the forward node. Spin is the while loop in the lock. In general, the benefit of this implementation is to ensure fair competition among all waiting threads, and not to compete with the same variable, because each thread only needs to wait for its own release. The advantage of spin is that the thread does not need to sleep or wake up, reducing the overhead of system calls.

public static void main(String[] args) {    final ClhSpinLock lock = new ClhSpinLock();    lock.lock();    for (int i = 0; i < 10; i++) {        new Thread(new Runnable() {            @Override            public void run() {                lock.lock();                System.out.println(Thread.currentThread().getId() + " acquired the lock!");                lock.unlock();            }        }).start();        Thread.sleep(100);    }    System.out.println("main thread unlock!");    lock.unlock();}

The running result of the code above should be exactly the same as that in the previous article.

ClhSpinLockThe implementation of the Node class is very simple with only one Boolean value,AbstractQueuedSynchronizer$NodeThe implementation is a little complicated, probably like this:

     +------+  prev +-----+       +-----+head |      | <---- |     | <---- |     |  tail     +------+       +-----+       +-----+
  • Head: Header pointer
  • Tail: tail pointer
  • Prev: pointer to forward
  • Next: This pointer graph is not shown. It is opposite to prev and points to the next

The key difference is the next pointer. This is because the thread in AQS is not always spinning, but may sleep and wake up repeatedly, this requires the next pointer to find the next pointer to wake up the lock, that is, the AQS waits for the queue to be awakened by the next pointer. AQS combines the advantages of spin and sleep/Wakeup methods.

Thread sleep and wake-up are used in my next article.LockSupport.

Last, the aboveClhSpinLockAnother key point in the class islockAnnotations in the method:

A cas operation can add the node corresponding to the current thread to the queue and obtain its successor.

In fact, the entire AQS framework is based on CAS, and these atomic operations are the core of multi-thread competition. Many of AQS's code is bypassed to reduce competition. I will be behindAbstractQueuedSynchronizerThe source code analysis is described in detail.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.