AbstractQueuedSynchronizer-addWaiter函数

addWaiter(Node node)函数作用:

例如对于计数信号量Semaphore,在某个线程中调用acquire(int permits)函数时候,例如semaphore.acquire(0),在进一步调用tryAcquireShared(arg)的时候由于可用的permits值不足,而返回小于0值的时候,进而执行函数doAcquireSharedInterruptibly(int arg),则首先会把以该线程和Node.SHARED为参数构造新节点Node node = new Node(Thread.currentThread(), mode),插入到当前等待队列中。

 private Node enq(final Node node) {
        for (;;) {
            Node t = tail;
            if (t == null) {
                if (compareAndSetHead(new Node()))
                    tail = head;
            } else {
                node.prev = t;
                if (compareAndSetTail(t, node)) {
                    t.next = node;
                    return t;
                }
            }
        }
    }

  
    private Node addWaiter(Node mode) {
        Node node = new Node(Thread.currentThread(), mode);
        Node pred = tail;
        if (pred != null) {
            node.prev = pred;
            if (compareAndSetTail(pred, node)) {
                pred.next = node;
                return node;
            }
        }
        enq(node);
        return node;
    }

enq函数是在队列为空的时候插入第一个新节点时候使用:

队列为空插入第一个节点后的队列情况:

队列非空插入后续节点后的队列情况:

完整测试代码,debug模式可以观察出插入第一个节点的情况:

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class Main {
    private static Semaphore semaphore = new Semaphore(-2, true);

    public static void main(String[] args) throws InterruptedException {

        Thread thread0 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Thread0 over!");
                semaphore.release();
            }
        });

        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Thread1 over!");
                semaphore.release();
            }
        });

        thread0.start();
        TimeUnit.SECONDS.sleep(1);
        semaphore.acquire(0);//因为获取不到0个permits所以会线程会阻塞在这里!
        TimeUnit.SECONDS.sleep(1);
        thread1.start();
       

        System.out.println("Main Over!");
    }
}
原文地址:https://www.cnblogs.com/iuyy/p/13569620.html