CountDownLatch介绍
CountDownLatch是java.util.concurrent包中的类。
一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。其实就是一个或者多个线程等待其他线程执行完成之后自己才开始执行。
例子:
就像一个教室里的学生,班长要等待所有同学都出教室了,最后班长再把问锁上走人。班长就是那个一直被阻塞的线程,知道别的线程都执行完毕自己再执行。
代码如下:
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(6);
//初始计数为6
for(int i=1;i<=6;i++){
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"放学回家");
countDownLatch.countDown(); //计数--
}
},String.valueOf(i)).start();
}
countDownLatch.await(); //主线程一直等待直到countDownLatch变量减到0才开始执行
System.out.println(Thread.currentThread().getName()+"班长最后锁门回家");
}
结果:
1放学回家
2放学回家
3放学回家
4放学回家
5放学回家
6放学回家
main班长最后锁门回家
结论:开启6个线程直到这6个线程执行完成之后主线程才被唤醒最后执行。就像火箭发射,所有的准备工作做完最后才点火起飞。
CyclicBarrier介绍
CyclicBarrier是java.util.concurrent包中的类。
Cyclic(循环) Barrier(屏障)
一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点。
也即是说让一组线程到达一个屏障时被阻塞,直到最后一个线程到达屏障时,屏障才会消失,所有被屏障阻塞的线程才会继续干活。
例子:
就像小时候看的七龙珠一样,只要集齐7个龙珠才能复活。就是集齐不够7颗龙珠就一直被阻塞,直到集齐最后一颗突破屏障。才会执行
代码如下:
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(7,() ->{
System.out.println("复活");
});
for (int i=1;i<=7;i++){
final int temp = i;
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"集齐第"+temp+"颗龙珠");
try {
cyclicBarrier.await(); //线程等待
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
},String.valueOf(i)).start();
}
}
结果:
1集齐第1颗龙珠
2集齐第2颗龙珠
3集齐第3颗龙珠
4集齐第4颗龙珠
5集齐第5颗龙珠
6集齐第6颗龙珠
7集齐第7颗龙珠
复活
和上边的CountDownLatch(闭锁)一样只不过上边的是减1直到零才执行,Cyclicbarrier是加直到加到几才执行,构造里面可以传两个参数,第一个参数是直到几个线程都等待,才会执行第二个参数是最终执行的线程。
Semaphore(信号灯) Sai mu fao er
就是很多线程抢占很多把锁,多对多的关系,抢到了就用,抢不到的就等。就像抢车位一样,假如有3个车位,6辆车。肯定第一次就只有三个车有车位,另三个车等待。提高并发量。
代码如下:
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3); //模拟三个车位,
for(int i=1;i<=6;i++){
new Thread(new Runnable() {
@Override
public void run() {
try {
semaphore.acquire(); //占了一个车位 获得一把锁
System.out.println(Thread.currentThread().getName()+"占了车位");
Thread.sleep(4000); //用了三秒钟
System.out.println(Thread.currentThread().getName()+"走了");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
semaphore.release(); //释放车位锁
}
}
},String.valueOf(i)).start();
}
}
结果:
2占了车位
1占了车位
3占了车位
2走了
3走了
1走了
5占了车位
4占了车位
6占了车位
5走了
4走了
6走了