CountDownLatch:让一些线程阻塞直到另一些线程完成一系列操作后才被唤醒。
CountDownLatch主要有两个方法,当一个或多个线程调用await方法时,调用线程会被阻塞。其它线程调用countDown方法会将计数器减一(调用countDown方法的线程不会阻塞),当计数器的值变为零时,因调用await方法被阻塞的线程会被唤醒,继续执行。
具体代码演示:
秦灭六国
package com.company;
import lombok.Getter;
enum CountryEnum{
ONE(1,"齐"),TWO(2,"楚"),THREE(3,"燕"),
FOUR(4,"赵"),FIVE(5,"魏"),SIX(6,"韩");
private Integer code;
private String message;
public Integer getCode() {
return code;
}
public String getMessage() {
return message;
}
CountryEnum(Integer code, String message) {
this.code = code;
this.message = message;
}
public static CountryEnum CountryEnum_foreach(int index){
CountryEnum[] countryEnums = CountryEnum.values();
for (CountryEnum c:countryEnums) {
if (index == c.getCode()){
return c;
}
}
return null;
}
}
package com.company;
import lombok.Getter;
import java.util.concurrent.CountDownLatch;
public class CountDownLatchDemo {
public static void main(String[] args) throws Exception {
CountDownLatch countDownLatch = new CountDownLatch(6);
for(int i = 1; i <= 6; i++){
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"国被灭");
countDownLatch.countDown();
},CountryEnum.CountryEnum_foreach(i).getMessage()).start();
}
countDownLatch.await();
System.out.println("秦国统一");
}
}
CyclicBarrier的字面意思是可循环(Cyclic) 使用的屏障(Barrier) 。它要做的事情是,
让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,
屏障才会开门,所有被屏障拦截的线程才会继续干活,线程进入屏障通过CyclicBarrier的await()方法。
代码演示:
七龙珠召唤神龙
package com.company;
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++){
final int temp = i;
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"\t收集到第" + temp + "颗龙珠");
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
},String.valueOf(i)).start();
}
}
}
Semaphore也是一个线程同步的辅助类,可以维护当前访问自身的线程个数,并提供了同步机制。使用Semaphore可以控制同时访问资源的线程个数,例如,实现一个文件允许的并发访问数。
Semaphore的主要方法摘要:
void acquire():从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。(抢占)
void release():释放一个许可,将其返回给信号量。(释放)
代码演示:
模拟停车,6辆车抢占3个停车位
package com.company;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class SemaphoreDemo {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3);//模拟停车 3个停车位
for(int i = 1; i <=6; i++){//6辆车
new Thread(()->{
try {
semaphore.acquire();//抢占
System.out.println(Thread.currentThread().getName()+"抢到车位");
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"停车三秒后离开");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
semaphore.release();//释放
}
},String.valueOf(i)).start();
}
}
}