1.CountDownLatch相关API使用
package com.ctgu.juc_project.source;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CountDownLatchTest {
public static int threadCount = 3;
public static int waitCount = 2;
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(threadCount);
ExecutorService runPool = Executors.newFixedThreadPool(threadCount);
ExecutorService waitPool = Executors.newFixedThreadPool(waitCount);
for (int i = 0; i < threadCount; i++) {
runPool.execute(() -> {
System.out.println(Thread.currentThread().getName() + ": RUNNING");
countDownLatch.countDown();
});
}
countDownLatch.await();
System.out.println(Thread.currentThread().getName() + ": WAITING");
for (int j = 0; j < waitCount; j++) {
waitPool.execute(() -> {
System.out.println(Thread.currentThread().getName() + ": WAITING");
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
runPool.shutdown();
waitPool.shutdown();
}
}
运行结果
pool-1-thread-2: RUNNING
pool-1-thread-3: RUNNING
pool-1-thread-1: RUNNING
main: WAITING
pool-2-thread-1: WAITING
pool-2-thread-2: WAITING
2.CountDownLatch相关API解读
- new CountDownLatch(count)
new Sync(count)
setState(count)
private volatile int state
初始化设置共享资源volatile state,用于CAS操作
- countDown()
tryReleaseShared(int releases) CAS state - 1
当state - 1 == 0 时,执行doReleaseShared()
把当前结点设置为SIGNAL或者PROPAGATE,如果当前结点不是头结点也不是尾结点,先判断当前结点的状态位是否为SIGNAL,
如果是就设置为0,因为共享模式下更多使用PROPAGATE来传播,SIGNAL会被经过两步改为PROPAGATE
- await()
doAcquireSharedInterruptibly()
在双向链表中生成共享模式的节点,第一次生成会先生成头结点然后指向Node(Shared),不然就加到上个节点的尾部
死循环堵塞,直到CAS将state减到0时,移除头结点,并将当前节点设置为头结点,清空GC
网友评论