CountDownLatch减法计数器
每次有线程调用countDownLatch.countDown()数量就-1
数量减到0时,countDownLatch.await()会被唤醒,继续向下执行
public class CountDownLatchDemo {
public static void main(String[] args) throws InterruptedException {
//总数是6,必须要执行任务的时候再使用
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 1; i <= 6; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"go out");
countDownLatch.countDown();//数量-1
},String.valueOf(i)).start();
}
countDownLatch.await();//等待计数器归零,然后再执行下面的操作
//countDownLatch.await()不被唤醒,后面的代码不会执行
System.out.println("finish!");
}
}
CyclicBarrier加法计数器
线程每调用一次cyclicBarrier.await()计数器+1
计数器达到总数后,执行定义的操作
public class CyclicBarrierDemo {
public static void main(String[] args) {
//第一个参数:总数;第二个参数:达到总数后将进行的操作
CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> {
System.out.println("召唤神龙");
});
for (int i = 1; i <= 7; i++) {
//lambda表达式无法直接操作到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();
}
},String.valueOf(i)).start();
}
}
}
Semaphore信号量
多个共享资源互斥使用;并发限流,控制最大的线程数
semaphore.acquire()如果资源被占满,排队等待获得资源
semaphore.release()释放资源,唤醒等待的线程;将当前的信号量释放+1,唤醒等待的线程
//3个车位6辆车的分配问题
public class SemaphoreDemo {
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()+"抢到车位");
TimeUnit.SECONDS.sleep(2);//执行任务,业务代码
System.out.println(Thread.currentThread().getName()+"释放车位");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();//离开车位
}
},String.valueOf(i)).start();
}
}
}