首先,一定要注意一点,就是调用countDown()方法时,必须放到finally执行,否则会发生永远阻塞。
public class CountDownLathTest {public static void main(String[] args) {CountDownLatch countDownLatch = new CountDownLatch(3);IntStream.range(0,3).forEach(i -> new Thread(()->{try {Thread.sleep(2000);System.out.println("hello");} catch (InterruptedException e) {e.printStackTrace();}finally {countDownLatch.countDown();}}).start());System.out.println("主线程运行");try {countDownLatch.await();System.out.println("所有线程执行完毕");} catch (InterruptedException e) {e.printStackTrace();}}}
await源码
public void await() throws InterruptedException {// 这个1实际上只是为了AQS执行,并无实际意义sync.acquireSharedInterruptibly(1);}public final void acquireSharedInterruptibly(int arg)throws InterruptedException {if (Thread.interrupted())throw new InterruptedException();if (tryAcquireShared(arg) < 0)// 执行后续线程代码doAcquireSharedInterruptibly(arg);}// 获取计数protected int tryAcquireShared(int acquires) {return (getState() == 0) ? 1 : -1;}
countDown源码
public void countDown() {sync.releaseShared(1);}public final boolean releaseShared(int arg) {if (tryReleaseShared(arg)) {// 唤醒线程doReleaseShared();return true;}return false;}protected boolean tryReleaseShared(int releases) {// 将计数器的值每次减一,当值归零后发出信号for (;;) {// 获取计数器的值int c = getState();// 计数器的值归零后直接返回if (c == 0)return false;// CAS处理,减一int nextc = c-1;if (compareAndSetState(c, nextc))// 经过减一后,nextc才会变为0return nextc == 0;}}
