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!"); } }