本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
CountDownLatch 让班长线程阻塞,直到同学线程CountDownLatch到0,再执行
让一些线程阻塞直到另一些线程完成一系列操作后才被唤醒
CountDownLatch主要有两个方法,当一个或多个线程调用await方法时,调用线程会被阻塞。其它线程调用countDown方法会将计数器减1(调用countDown方法的线程不会阻塞),当计数器的值变为零时,因调用await方法被阻塞的线程会破唤醒,继续执行。
火箭发射10 9 8到0
await方法将会执行,直到计数到0
package com.wsx.countDown;
import java.util.concurrent.CountDownLatch;
public class CountDownDemo {
public static void main(String[] args) {
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 0; i < 6; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"号同学离开");
countDownLatch.countDown();
},String.valueOf(i)).start();
}
try { countDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println(Thread.currentThread().getName()+"班长锁门");
}
}
复制代码
枚举 :相当于一个数据库 解耦合 不用建立连接关闭连接
package com.wsx.countDown;
public enum CountryEnum {
ONE(1,"齐"),TWO(2,"楚"),THREE(3,"燕"),FOUR(4,"汉"),FIVE(5,"赵"),SIX(6,"魏");
private Integer retCode;
private String retName;
public Integer getRetCode() {
return retCode;
}
public void setRetCode(Integer retCode) {
this.retCode = retCode;
}
public String getRetName() {
return retName;
}
public void setRetName(String retName) {
this.retName = retName;
}
CountryEnum(Integer retCode, String retName) {
this.retCode = retCode;
this.retName = retName;
}
public static CountryEnum findCountry(int index){
CountryEnum[] values = CountryEnum.values();
for (CountryEnum element:values) {
if(index == element.getRetCode()){
return element;
}
}
return null;
}
}
复制代码
package com.wsx.countDown;
import java.util.concurrent.CountDownLatch;
public class CountDownDemo2 {
public static void main(String[] args) {
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 1; i <= 6; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"国被灭");
countDownLatch.countDown();
},CountryEnum.findCountry(i).getRetName()).start();
}
try { countDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println(Thread.currentThread().getName()+"秦国赢");
}
}
复制代码
CyclicBarrier
举例:到一个屏障点,到七个龙珠都集齐才能召唤神龙,找到第一个,要等剩下的六个都找到,再继续工作
CyclicBarrier的字面意思是可循环(Cyclic) 使用的屏障(Barrier) 。它要做的事情是,让一-组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活,线程进入屏障通过CyclicBarrier的await)方法。 内存屏障点
package com.wsx.cyclicBarrier;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierDemo {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{
System.out.println("召唤神龙");
});
for (int i = 1; i <= 7; i++) {
int tempint = i;
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"第"+tempint+"龙珠");
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
},String.valueOf(i)).start();
}
}
}
复制代码
Semaphore
有一个上限,假如,两个车位车位相当于限制并发数量,四个车,需要前两个车停完之后,其他的车才能再来停(争车位,抢红包,秒杀,电商并发,微信红包)
多个线程抢多个资源
信号量主要用于两个目的,一个是用于多个共享资源的互斥使用,另-一个用于并发线程数的控制。
package com.wsx.semaPhore;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class SemaPhoreDemo {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(2);
for (int i = 1; i <= 4; i++) {
new Thread(()->{
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName()+"号停车");
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName()+"号离开");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
}
},String.valueOf(i)).start();
}
}
}