Java进阶常用的辅助类(CountDownLatch 减法计数器、CyclicBarrier 加法计数器、Semaphore 计数信号量)
一、CountDownLatch 减法计数器
1、简介
- 减法计数器
- 允许一个或多个线程等待直到其它线程中执行的一组操作完成的同步辅助
2、代码案例
package com.sgz.add;
import java.util.concurrent.CountDownLatch;
public class CountDownLatchDemo {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 1; i <= 6; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "Go out");
countDownLatch.countDown();
}, String.valueOf(i)).start();
}
countDownLatch.await();
System.out.println("Close Door");
}
}
3、原理
- countDownLatch.countDown(); // 数量-1
- countDownLatch.await(); // 等待计数器归零,然后再向下执行
- 每次有线程调用countDown()数量-1,假设计数器变为0, countDownLatch.await(); 就会被唤醒,继续执行!
二、CyclicBarrier 加法计数器
1、简介
- 加法计数器
- 允许一组线程全部等待彼此达到共同屏障点的同步辅助
2、代码案例
package com.sgz.add;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierDemo {
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(() -> {
System.out.println(Thread.currentThread().getName() + "收集" + temp + "个龙珠");
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
}
}
三、Semaphore 信号量
1、简介
- 信号量
- 一个计数信号量。在概念上,信号量维持一组许可证。如果有必要,每个acquire()都会阻塞,直到许可证可用,然后才能使用它。
2、代码案例
package com.sgz.add;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class SemaphoreDemo {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3);
for (int i = 1; i <= 6; i++) {
new Thread(()->{
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + "抢到车位");
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread().getName() + "离开车位");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
semaphore.release();
}
},String.valueOf(i)).start();
}
}
}
3、原理
- semaphore.acquire(); // 获取,假设如果已经满了,等待,等待被释放为止
- semaphore.release(); // 释放,会将当前的信号量释放 +1,然后唤醒等待的线程
- 作用:多个共享资源互斥的使用!并发限流,控制最大的线程数!