package function.thread;
import java.util.concurrent.CountDownLatch;
/**
* 示例:CountDownLatch的使用举例
* CountDownLatch是一个功能强大且易于使用的对象,主要适用于
* 当前线程必须等待一个或多个事件发生的时候
*/
public class TestCountDownLatch {
private static final int N = 10;
public static void main(String[] args) throws InterruptedException {
CountDownLatch doneSignal = new CountDownLatch(N);
CountDownLatch startSignal = new CountDownLatch(1);//开始执行信号
for (int i = 1; i <= N; i++) {
//线程启动后,处于就绪状态
new Thread(new Worker(i, doneSignal, startSignal)).start();//线程启动了
}
System.out.println("begin------------");
//子线程都调用了await方法,所以当前线程不变更计数器,子线程就会被阻塞
startSignal.countDown();//计数器大于0,线程被阻塞。另外,阻塞并不等于线程执行完毕
//sleep太久,子线程可能都执行完毕了
Thread.sleep(10);//为了更好地看到各线程的竞争,否则可能是主线程一直先执行如下语句
System.out.println(" 我是主线程,也是线程。我也会加入到和子线程竞争的队伍中.....");
//此处可以是当前线程的阻塞点
doneSignal.await();//当前线程等待所有的线程执行完毕
System.out.println("main thread end 。。。。。。");
}
static class Worker implements Runnable {
private final CountDownLatch doneSignal;
private final CountDownLatch startSignal;
private int beginIndex;
Worker(int beginIndex, CountDownLatch doneSignal,
CountDownLatch startSignal) {
this.startSignal = startSignal;
this.beginIndex = beginIndex;
this.doneSignal = doneSignal;
}
public void run() {
try {
//防止主线程未执行,而子线程先执行的情况,
//所以任何子线程都要先等待
startSignal.await(); //等待开始执行信号的发布,每个线程都会不断的检测放行的信号
beginIndex = (beginIndex - 1) * 10 + 1;
for (int i = beginIndex; i <= beginIndex + 10; i++) {
System.out.println(Thread.currentThread().getName()+":"+i);
}
Thread.sleep(5000);
System.out.println(Thread.currentThread().getName()+" wake up......");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
doneSignal.countDown();
}
}
}
}
运行结果:
begin------------
Thread-3:31
Thread-3:32
Thread-0:1
Thread-3:33
Thread-0:2
Thread-0:3
Thread-0:4
Thread-0:5
Thread-0:6
Thread-0:7
Thread-0:8
Thread-1:11
Thread-1:12
Thread-1:13
Thread-1:14
Thread-1:15
Thread-1:16
Thread-9:91
Thread-8:81
Thread-8:82
Thread-1:17
Thread-4:41
Thread-4:42
Thread-4:43
Thread-4:44
Thread-4:45
Thread-4:46
Thread-4:47
Thread-4:48
Thread-4:49
Thread-4:50
Thread-4:51
Thread-0:9
Thread-0:10
Thread-0:11
Thread-6:61
Thread-5:51
Thread-6:62
Thread-6:63
Thread-6:64
Thread-2:21
Thread-2:22
Thread-2:23
Thread-2:24
Thread-2:25
Thread-2:26
Thread-2:27
Thread-7:71
Thread-3:34
Thread-7:72
Thread-3:35
Thread-2:28
Thread-6:65
Thread-5:52
Thread-1:18
Thread-1:19
Thread-1:20
Thread-8:83
Thread-8:84
Thread-9:92
Thread-8:85
Thread-1:21
Thread-5:53
Thread-6:66
Thread-2:29
Thread-3:36
Thread-7:73
Thread-3:37
Thread-2:30
Thread-2:31
Thread-6:67
Thread-6:68
Thread-5:54
Thread-8:86
Thread-9:93
Thread-9:94
Thread-8:87
Thread-5:55
Thread-5:56
Thread-6:69
Thread-3:38
Thread-7:74
Thread-3:39
Thread-6:70
Thread-5:57
Thread-8:88
Thread-9:95
Thread-8:89
Thread-5:58
Thread-5:59
Thread-5:60
Thread-5:61
Thread-6:71
Thread-3:40
Thread-7:75
Thread-3:41
Thread-8:90
Thread-9:96
Thread-8:91
Thread-7:76
Thread-9:97
Thread-9:98
Thread-9:99
Thread-9:100
Thread-7:77
Thread-9:101
Thread-7:78
Thread-7:79
Thread-7:80
Thread-7:81
我是主线程,也是线程。我也会加入到和子线程竞争的队伍中.....
Thread-4 wake up......
Thread-0 wake up......
Thread-1 wake up......
Thread-2 wake up......
Thread-3 wake up......
Thread-6 wake up......
Thread-8 wake up......
Thread-5 wake up......
Thread-9 wake up......
Thread-7 wake up......
main thread end 。。。。。。