2022.8.21 常用的辅助类
8、常用的辅助类
CountDownLatch
减法计数器: 实现调用几次线程后 再触发某一个任务
一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
package com.xing.demo03;
import java.util.concurrent.CountDownLatch;
//减法计数器 等待屋子里的6个人全部出门后再关门
public class CountDownLatchDemo {
public static void main(String[] args) throws InterruptedException {
//倒计时 总数是6 必须要执行任务的时候使用
CountDownLatch countDownLatch = new CountDownLatch(6);
// 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(); // 等待计数器归零,然后再向下执行
System.out.println("close door");
}
}
总结: countDownLatch.countDown();会让其自动减一 ,而在CountDownLatch下用await等待会讲等待其计数器归零时才会再向下执行,防止门提前关了里面的人出不去
CyclicBarrier
package com.xing.demo03;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
// 加法计数器 集齐七颗龙珠
public class CyclicBarrierDemo {
public static void main(String[] args) {
//参数1:计数 参数2:计数完成后执行一个线程 参数2可以不写
CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{
System.out.println("召唤神龙");
});
for (int i = 0; i<7;i++){
final int temp = i;
//lamdba能操作到变量i吗 不能 通过一个中间变量
new Thread(()->{
System.out.println(Thread.currentThread().getName() + "收集" + temp + "个龙珠");
try{
cyclicBarrier.await();//等待计数器变成7
} catch (BrokenBarrierException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
}
总结:CyclicBarrier可以设置指定最终达到的数值(代表for里的最大数),还能创建线程,CyclicBarrier下的await会等待其数值达到最终数值才会执行最终数值旁边的Runnable线程
Semaphore
Semaphore:信号量
为了限流
限流/抢车位!6车—3个停车位置
package com.xing.demo03;
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 {
// 3个线程中的某个线程获得
semaphore.acquire();//获得
System.out.println(Thread.currentThread().getName() + "抢到车位");
TimeUnit.SECONDS.sleep(2);//停2秒
//离开车位
System.out.println(Thread.currentThread().getName() + "离开车位");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();//释放
}
}, String.valueOf(i)).start();
}
}
}
-
semaphore.acquire():获得,假设如果已经满了,等待,等待被释放为止!
-
semaphore.release():释放,会将当前的信号量(3个停车位)释放 + 1,然后唤醒等待的线程!
作用: 多个共享资源互斥的使用!并发限流,控制最大的线程数!