CountDownLatch和CyclicBarrier类似,只不过CountDownLatch是控制线程完成的数量,而CyclicBarrier是控制线程阻塞的数量,换言之,一个做线程减法,一个做线程加法,且CyclicBarrier是可往复使用的,类似批处理的感觉,就是插入十万数据,一次性插入一万,达到一万,插入一次…直到十万数据都插入完成。
使用案例
public static void main(String[] args) throws InterruptedException {
//CountDownLatch部分
CountDownLatch latch = new CountDownLatch(5);
for(int i = 0; i < 5; i++){
new Thread(){
@Override
public void run() {
try{
System.out.println(Thread.currentThread().getId()+"做完了,等待中");
}catch (Exception e) {
e.printStackTrace();
}finally {
latch.countDown();
}
}
}.start();
}
latch.await();
System.out.println("【CountDownLatch】所有线程做完了");
//CyclicBarrier部分
CyclicBarrier barrier = new CyclicBarrier(5, () -> {
System.out.println("【CyclicBarrier】所有线程做完了,开始下一批...");
});
for(int i = 0; i < 10; i++){
new Thread(){
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getId()+"做完了,等待其他线程");
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}.start();
}
}
执行结果
11做完了,等待中
12做完了,等待中
13做完了,等待中
14做完了,等待中
15做完了,等待中
【CountDownLatch】所有线程做完了
16做完了,等待其他线程
17做完了,等待其他线程
18做完了,等待其他线程
19做完了,等待其他线程
20做完了,等待其他线程
【CyclicBarrier】所有线程做完了,开始下一批…
21做完了,等待其他线程
22做完了,等待其他线程
23做完了,等待其他线程
24做完了,等待其他线程
25做完了,等待其他线程
【CyclicBarrier】所有线程做完了,开始下一批…
Semaphore
主要用来控制资源访问的线程数
模拟使用场景。
public static void main(String[] args) throws InterruptedException {
Random rm = new Random();
Semaphore semaphore = new Semaphore(3);
for(int i = 0; i < 7; i++) {
int time = rm.nextInt(2000) + 1000;
new Thread(){
@Override
public void run() {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getId() + "开始上网,占用机位...");
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
System.out.println(Thread.currentThread().getId() + "上网结束,释放机位...");
semaphore.release();
}
}
}.start();
}
}
执行结果
11开始上网,占用机位…
12开始上网,占用机位…
13开始上网,占用机位…
11上网结束,释放机位…
14开始上网,占用机位…
12上网结束,释放机位…
15开始上网,占用机位…
14上网结束,释放机位…
16开始上网,占用机位…
13上网结束,释放机位…
17开始上网,占用机位…
17上网结束,释放机位…
15上网结束,释放机位…
16上网结束,释放机位…
CountDownLatch,CyclicBarrier,Semaphore底层还是依据AbstractQueuedSynchronizer来实现的。
ps:后续增加aqs的相关说明