序言:
JUC也就java.util.conCurrent的简称,基本上JAVA中涉及到多线程的类都是在这个包下的。
JUC包下的大多组件都是基于AQS基类的,今天我们简单聊一下JUC下的三大类CountDownLatch,CyclicBarrier,Semaphore
CountDownLatch
CountDownLatch的中文意思就是倒计数器,通过构造函数来指定计时器的大小,下面通过一段代码来演示一下!
CountDownLatch countDownLatch=new CountDownLatch(3);
for (int i=0;i<3;i++){
int finalI = i;
new Thread(()->{
System.out.println("编号为"+ finalI +"的同学进教室了");
countDownLatch.countDown();
}).start();
}
try {
countDownLatch.await();
System.out.println("三名同学都到了可以上课了");
} catch (InterruptedException e) {
e.printStackTrace();
}
运行结果:
每次调用countDown方法都会让计数器减一,当计数器为0后会执行await后的代码。
CyclicBarrier
CyclicBarrier的话是一个正计数器,它也可以通过构造函数来指定计数器的大小,同时CyclicBarrier在构造函数中还可以传递一个线程进去,当计数器达到指定阈值后,执行传递的线程,同时CyclicBarrier是可重复利用度。
CyclicBarrier cyclicBarrier = new CyclicBarrier(7, new Thread(()-> System.out.println("7颗龙珠收集完毕,召唤神龙")));
for (int i=1;i<8;i++){
int finalI=i;
new Thread(()->{
System.out.println("收集第"+finalI+"颗龙珠");
try {
cyclicBarrier.await();
System.out.println("^^");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
运行结果:
从运行结果可以看出,当计数器达到阈值后,先会执行构造函数中的线程,然后会执行多个线程一起执行await()方法后的代码。
CountDownLatch和CyclicBarrier的区别
- CountDownLatch是倒计数,CyclicBarrier是正计数
- CountDownLatch不可复用,CyclicBarrier可复用
- CyclicBarrier构造函数还可传入一个线程
- CountDownLatch是多个线程达到临界点后某一线程向下执行,CyclicBarrier则是多个线程达到临界点后一起向下执行
Semaphore
semaphore的中文意思就是信号,它的作用也类似于一个信号,传统情况下添加锁操作后,同一时刻只允许一个线程来访问我们的代码,semaphore的话可以传入一个值,这个值代表了允许访问代码的最大线程数,也就是说使用semaphore来控制代码块是允许多个线程来访问的。
代码如下:
Semaphore semaphore=new Semaphore(3);//指定资源的个数
System.out.println("共有3个车位");
for (int i=0;i<6;i++){
int finalI=i;
new Thread(()->{
try {
semaphore.acquire();//抢占资源,当资源被占用时处于阻塞状态
System.out.println(finalI+"抢占到车位");
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
System.out.println(finalI+"把车开走了");
semaphore.release();//释放资源
}
}).start();
}
}
运行结果:
平时semaphore也可以来做一些限流之类的操作。
总结
希望我们每个人都可以乘风破浪,越来越优秀吧,与君共勉。