【应用场景】
有这样一种业务需求:需要几个线程完成之后,主线程才能继续。举个例子:车辆出厂,一辆车出厂,需要生产各个配件,并且安装,都完成后还需要质检,最后才可以出厂。类似这样的需求,我们可以考虑使用CountDownLatch来控制并发。
【CountDownLatch】
java.util.concurrent包有这样一个类,类似计数器,其内部维护着一个加锁的count计数,CountDownLatch通过构造函数传入一个初始计数值,调用cutDown()方法使count减1;调用await()方法,则线程就会一直阻塞,直到其他线程通过cutDown方法,将计数减到0,才可以继续执行。
public class CountDownLatch {
private static final class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = 4982264981922014374L;
Sync(int count) {
setState(count);
}
int getCount() {
return getState();
}
protected int tryAcquireShared(int acquires) {
return (getState() == 0) ? 1 : -1;
}
protected boolean tryReleaseShared(int releases) {
for (;;) {
int c = getState();
if (c == 0)
return false;
int nextc = c-1;
if (compareAndSetState(c, nextc))
return nextc == 0;
}
}
}
private final Sync sync;
public CountDownLatch(int count) {
if (count < 0) throw new IllegalArgumentException("count < 0");
this.sync = new Sync(count);
}
public void await() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
public boolean await(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout));
}
public void countDown() {
sync.releaseShared(1);
}
public long getCount() {
return sync.getCount();
}
public String toString() {
return super.toString() + "[Count = " + sync.getCount() + "]";
}
}
【应用实现】
package zheng;
import java.util.concurrent.CountDownLatch;
public class test {
public enum EnumTest {
发动机, 底盘, 车身, 其他;// 线程名称
}
public static void main(String[] args) {
final CountDownLatch countDownLatch = new CountDownLatch(3);
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("主线程:正在等待车辆质检");
try {
countDownLatch.await();
System.out.println("发动机、底盘、车身、其他,已配置好, 车辆出厂啦");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
for (EnumTest threadName : EnumTest.values()) {
final String tN = String.valueOf(threadName);
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(tN + " 正在配置");
try {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(tN + " 安装完成");
countDownLatch.countDown();
}
}).start();
}
}
}
运行结果: