CountDownLatch、Semaphore、FutureTask源码解析
本文的主要内容是认识CountDownLatch、Semaphore、FutureTask的源码,这三个类在AQS中都用的是共享模式的,而且是可中断的,不同的是各自的请求锁和释放锁的操作,先说他们的不同点,在来说相同点。
?
首先看看CountDownLatch(闭锁),这个类在构建的时候初始一个阀值N,每调用一次countDown()后,N将减一直到为0时,线程才可以通过,下面来看看请求锁的代码
private void setHeadAndPropagate(Node node, int propagate) { setHead(node); if (propagate > 0 && node.waitStatus != 0) { /* * Don't bother fully figuring out successor. If it * looks null, call unparkSuccessor anyway to be safe. */ Node s = node.next; if (s == null || s.isShared()) unparkSuccessor(node); } }
?将当前节点设置为头结点,如果有足够的许可,并且后面还有等待节点就唤醒下一个节点,这一点和独占模式比起来就有一点共享的意思,比如CountDownLatch,只要countDown次数足够全部的等待线程都会唤醒;Semaphore,只要还有信号量就会继续唤醒等待线程;FutureTask,只要任务完成,所有的等待线程都将唤醒。
这里的中断机制是,线程被中断后,先把节点从同步队列中出队后抛出中断异常,java中中断就是这种模式的:线程A中断线程B后,由线程B选择适当的时候响应中断,这个操作由线程B自己处理的。
?
以上三个类都是AQS在共享模式下的应用。