• 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!");
        }
    }
  • 相关阅读:
    向内的寻找
    了解潜意识
    NOI2014 Day1
    NOI2011 Day1
    NOI2012 Day2
    NOI2012 Day1
    NOI2013 Day2
    NOI2013 Day1
    拉格朗日乘数法
    NOI2015 Day2
  • 原文地址:https://www.cnblogs.com/iuyy/p/13569620.html
Copyright © 2020-2023  润新知