这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战
1.CountDownLatch
用法:通过计数器 来限制某一线程在其他线程之后在执行,示例代码如下
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(10);
for (int i = 0; i <10 ; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+" \t"+"进来了");
countDownLatch.countDown();
},String.valueOf(i)).start();
}
countDownLatch.await();
System.out.println("主线程开始了");
}
运行结果:
0 进来了
1 进来了
2 进来了
3 进来了
7 进来了
4 进来了
5 进来了
6 进来了
8 进来了
9 进来了
主线程开始了
2.CyclicBarrier
解释:有多少个线程调用它的await方法后,再调用构造器里的线程 示例:
public static void main(String[] args) throws InterruptedException {
CyclicBarrier cyclicBarrier = new CyclicBarrier(10,new Runnable() {
@Override
public void run() {
System.out.println("当前线程"+Thread.currentThread().getName());
}
});
for (int i = 0; i <10 ; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+" \t"+"进来了");
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
},String.valueOf(i)).start();
}
}
以上代码就是说当有十个线程在await之后 ,执行runnable里面的方法,结果如下
1 进来了
5 进来了
4 进来了
3 进来了
2 进来了
0 进来了
6 进来了
7 进来了
9 进来了
8 进来了
当前线程8
3.Semaphore
可用来控制资源权限,例如只有三个停车位 有六辆车要停,这个时候只能有三个先停,其他三个进入等待状态,前三个完成走之后 把位置让出来,后面才能进 示例如下
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3);
for (int i = 0; i <6 ; i++) {
new Thread(()->{
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName()+" \t"+"进来了");
Thread.sleep(2000);
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
},String.valueOf(i)).start();
}
}
运行以上代码 会发现先进来三个 过了两秒后面三个才会进来
0 进来了
1 进来了
2 进来了
3 进来了
5 进来了
4 进来了
总结
CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同:
CountDownLatch一般用于某个线程A等待若干个其他线程执行完任务之后,它才执行;
而CyclicBarrier一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行;
另外,CountDownLatch是不能够重用的,而CyclicBarrier是可以重用的。
Semaphore其实和锁有点类似,它一般用于控制对某组资源的访问权限