在我个人理解下,这几个JUC包中的辅助类,实质上其实就是线程间的通信,只不过它们适用于不同的场景下。
1、CountDownLatch(减法计数器)
我们可以把它理解为一个加法计数器,计数器只有达到我们预先的设定的值之后,执行await方法的线程才可以继续往下执行。
demo
package juctest;
import java.util.concurrent.CountDownLatch;
public class CountDownLatchTest {
public static void main(String[] args) {
CountDownLatch countDownLatch = new CountDownLatch(7);
for(int i = 1;i<=7;i++){
new Thread(()->{
countDownLatch.countDown();
System.out.println(Thread.currentThread().getName()+"执行");
},String.valueOf(i)).start();
}
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("已经有七个线程累加了,然后我可以执行了");
}
}
执行结果:
D:\java\jdk1.8\bin\java.exe "-javaagent:D:\IDEA\IntelliJ IDEA
1执行
5执行
3执行
6执行
4执行
7执行
2执行
已经有七个线程累加了,然后我可以执行了
如果我们的执行计数一直没有减为0的话,那么等待的线程就一直会等待。
2、cyclicBarrier(栅栏)
可以理解为多个线程执行到同一位置后,再同时执行下面的代码。
也可以认为它是一个加法计数器,只有执行等待的线程数达到某个值后,才会一起执行后面的操作。
构造参数有两个:
public CyclicBarrier(int parties) {//只指定需要等待的数量的阈值
this(parties, null);
}
//多了一个Runnable对象,即达到等待线程的阈值之后,可以执行的操作
public CyclicBarrier(int parties, Runnable barrierAction) {
if (parties <= 0) throw new IllegalArgumentException();
this.parties = parties;
this.count = parties;
this.barrierCommand = barrierAction;
}
这里以集齐七龙珠,召唤神龙为例
package juctest;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierTest {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> {
System.out.println("召唤神龙");
});
for(int i = 1;i<=7;i++){
int temp = i;
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"收集了"+temp+"课龙珠");
try {
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("神龙出现,发射光波");
}).start();
}
}
}
执行结果:
Thread-0收集了1课龙珠
Thread-2收集了3课龙珠
Thread-1收集了2课龙珠
Thread-5收集了6课龙珠
Thread-3收集了4课龙珠
Thread-6收集了7课龙珠
Thread-4收集了5课龙珠
召唤神龙
神龙出现,发射光波
神龙出现,发射光波
神龙出现,发射光波
神龙出现,发射光波
神龙出现,发射光波
神龙出现,发射光波
神龙出现,发射光波
3、Semaphore(信号量)
Semaphore描述共享资源的数量。
作用:多个共享资源互斥使用
实际应用:并发限流,控制最大线程数
demo
package juctest;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class SemaphoreTest {
public static void main(String[] args) {
//比如有三个厕所的坑位
Semaphore semaphore = new Semaphore(3);
//有6个线程并发访问(7个人一起上厕所)
for(int i = 1;i<=7;i++){
new Thread(()->{
try {
//请求上厕所,请求资源
semaphore.acquire();
System.out.println("线程"+Thread.currentThread().getName()+"蹲下了");
TimeUnit.SECONDS.sleep(2);//在拉。。。。
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
semaphore.release();//释放信号量,起身离开,其他线程就可以进来了
}
},String.valueOf(i)).start();
}
}
}