2019年互联网(1.6)
一.JUC多线程及并发包
1.6.CountDownLatch/CyclicBarrier/Semaphore使用过吗?
CountDownLatch
让一些线程阻塞直到另外一些完成后才被唤醒
CountDownLatch主要有两个方法,
当一个或多个线程调用await方法时,调用线程会被阻塞.其他线程调用countDown方法计数器减1(调用countDown方法时线程不会阻塞)
当计数器的值变为0,因调用await方法被阻塞的线程会被唤醒,继续执行
案例:秦灭六国
先介绍一下枚举的使用
package com.ybzn._01.juc;
/**
* @author Hugo
* @time 2021/2/15
*/
public enum CountryEnum {
ONE(1,"齐"),TWO(2,"楚"),THREE(3,"燕"),FOUR(4,"赵"),FIVE(5,"魏"),SIX(6,"韩");
private Integer reCode;
private String reMessage;
CountryEnum (Integer reCode, String reMessage) {
this.reCode = reCode;
this.reMessage = reMessage;
}
public Integer getReCode () {
return reCode;
}
public String getReMessage () {
return reMessage;
}
public static CountryEnum foreach_CountEnum(int index){
CountryEnum[] values = CountryEnum.values();
for (CountryEnum countryEnum: values) {
if(index==countryEnum.getReCode()){
return countryEnum;
}
}
return null;
}
}
创建CountDownLatchDemo_1_6.java
Demo类
public class CountDownLatchDemo_1_6 {
public static void main (String[] args) throws InterruptedException {
CountDownLatch count =new CountDownLatch(6);//初始化数量
for (int i = 1; i <=6; i++) {
final int temp=i;
new Thread(() -> {
CountryEnum countryEnum = CountryEnum.foreach_CountEnum(temp);
System.out.println("线程第"+temp+"个\t"+countryEnum.getReMessage()+" 被灭");
count.countDown();
}, String.valueOf(i)).start();
}
count.await();
System.out.println("所有国家都被灭了");
}
}
结果分析: 当采用默认构造方法,初始化 Integer数量以后,每次countDown()减一,直到为0以后,await()方法才会执行
CyclicBarrier
CyclicBarrier的字面意思是可循环(Cyclic) 使用的屏障(barrier).
它要做的事情是,让一组线程到达一个屏障(也可以叫做同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,
所有被屏障拦截的线程才会继续干活,线程进入屏障通过
CyclicBarrier的await()
方法.
案例: 集齐7颗龙珠就能召唤神龙
案例代码``CyclicBarrierDemo.java`
public class CyclicBarrierDemo_1_6_2 {
public static void main (String[] args) throws BrokenBarrierException, InterruptedException {
CyclicBarrier barrier = new CyclicBarrier(7, () -> {
System.out.println("召唤神龙");
});//初始化变量
for (int i = 1; i <= 7; i++) {
final int temp=i;
new Thread(() -> {
try {
System.out.println("已收集龙珠编号\t " + temp);
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}, String.valueOf(i)).start();
}
}
}
结果分析: 初始化变量7,当await()
的数量达到了7以后,将会执行Runnable接口里面的方法
Samaphore
信号量的主要用户两个目的,一个是用于多喝共享资源的相互排斥使用,另一个用于并发资源数的控制.
案例:抢车位案例
代码演示:SamaphoreDemo.java
public class SemaphoreDemo_1_6_3 {
public static void main (String[] args) {
//模拟3个停车位
Semaphore semaphore = new Semaphore(3);
//模拟6部汽车
for (int i = 1; i <= 6; i++) {
new Thread(() -> {
try { //抢到资源
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + "\t抢到车位");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "\t 停3秒离开车位");
} catch (InterruptedException e) {
e.printStackTrace();
} finally { //释放资源
semaphore.release();
}
}, String.valueOf(i)).start();
}
}
}
结果分析:通过Semaphore.java 默认构造方法生成资源类数量
,使用acquire()方法请求一个资源,采用release()方法释放一个资源