7.常用的辅助类
感谢秦疆老师的JUC并发编程视频,更多了解哔哩哔哩搜索【狂神说Java】。
本文内容源于秦疆老师的JUC并发编程视频教程。给狂神推荐,点赞吧!
CountDownLatch(减法计数器)
代码测试:
package demo5;
import java.util.concurrent.CountDownLatch;
//计数器
public class CountDownLatchTest {
public static void main(String[] args) throws InterruptedException {
//总数是6 必须要执行任务的时候 ,再使用
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 0; 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!");
}
}
输出:
//未加计数器等待
0Go out!
5Go out!
4Go out!
3Go out!
2Go out!
Close Door!
1Go out!
//加计数器 先执行完线程任务 再执行
1Go out!
4Go out!
3Go out!
2Go out!
0Go out!
5Go out!
Close Door!
原理:
countDownLatch.countDown(); // 数量-1
countDownLatch.await(); // 等待计数器归零,然后再向下执行
//每次有线程调用 countDown() 数量-1,假设计数器变为0,countDownLatch.await()就会被唤醒,继续执行!
CyclicBarrier(加法计数器)
代码测试:
package demo5;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierTest {
public static void main(String[] args) {
/**
* 集齐7颗龙珠召唤神龙
*/
CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> {
System.out.println("召唤神龙成功!");
});
for (int i = 1; i <= 7; i++) {
//lambada操作到 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();
}
}
}
输出:
线程2收集了第2颗龙珠!
线程4收集了第4颗龙珠!
线程3收集了第3颗龙珠!
线程1收集了第1颗龙珠!
线程7收集了第7颗龙珠!
线程6收集了第6颗龙珠!
线程5收集了第5颗龙珠!
召唤神龙成功!
Semaphore(信号量)
代码测试: 抢车位!(6车—3个停车位置)
package demo5;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class SemaphoreTest {
public static void main(String[] args) {
//线程数量:停车位 限流!
Semaphore semaphore = new Semaphore(3);
for (int i = 1; i <= 6; i++) {
new Thread(() -> {
//acquire() 得到
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + "抢到车位!");
TimeUnit.SECONDS.sleep(2);
System.out.println(Thread.currentThread().getName() + "离开车位!");
} catch (Exception e) {
e.printStackTrace();
} finally {
semaphore.release();//release() 释放
}
}, "线程" + String.valueOf(i)).start();
}
}
}
输出:
线程1抢到车位!
线程3抢到车位!
线程2抢到车位!
线程1离开车位!
线程2离开车位!
线程3离开车位!
线程6抢到车位!
线程5抢到车位!
线程4抢到车位!
线程5离开车位!
线程4离开车位!
线程6离开车位!
原理:
semaphore.acquire()// 获得,假设如果已经满了,等待,等待被释放为止!
semaphore.release();// 释放,会将当前的信号量释放 + 1,然后唤醒等待的线程!
作用:
多个共享资源互斥的使用!并发限流,控制最大的线程数!