1、CountDownLatch
- 让一些线程阻塞直到另外一些完成后才被唤醒
- CountDownLatch主要有两个方法,当一个或有多个线程调用await方法时,调用的线程会被阻塞.其他线程调用countDown方法计数器减1(调用countDown方法时线程不会阻塞)
- 当计数器的值变为0,因调用await方法而被阻塞的线程会被唤醒,然后继续执行该线程的操作
package com.song.CountDownLatchTest;
import java.util.concurrent.CountDownLatch;
public class CountDownLatchDemo {
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(6);
for (int i = 1; i <= 6; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"\t被灭");
countDownLatch.countDown();
},CountryEnum.getCountryEnum(i).getMessage()).start();
}
countDownLatch.await();
System.out.println("秦始皇一统天下");
}
}
public enum CountryEnum {
ONE(1,"齐国"),TWO(2,"韩国"),THREE(3,"赵国"),FOUR(4,"楚国"),FIVE(5,"燕国"),SIX(6,"魏国");
private int reCode;
private String message;
CountryEnum(int reCode, String message) {
this.reCode = reCode;
this.message = message;
}
public static CountryEnum getCountryEnum(int i){
CountryEnum[] values = CountryEnum.values();
for (CountryEnum countryEnum : values) {
if (countryEnum.getReCode() == i) {
return countryEnum;
}
}
return null;
}
public int getReCode() {
return reCode;
}
public void setReCode(int reCode) {
this.reCode = reCode;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
###输出随机结果
齐国 被灭
燕国 被灭
魏国 被灭
楚国 被灭
韩国 被灭
赵国 被灭
秦始皇一统天下
Process finished with exit code 0
2、CyclicBarrier
- CyclicBarrier的字面意思是可循环(Cyclic) 使用的屏障(barrier)
- 它要做的事情是,让一组线程到达一个屏障(也可以叫做同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活,线程进入屏障通过CyclicBarrier的await()方法.
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();
}
}
}
###输出的随机结果
3 收集到第3颗龙珠
5 收集到第5颗龙珠
1 收集到第1颗龙珠
2 收集到第2颗龙珠
6 收集到第6颗龙珠
4 收集到第4颗龙珠
7 收集到第7颗龙珠
召唤神龙
Process finished with exit code 0
3、Semaphore
- 是一个线程同步的辅助类,可以维护当前访问自身的线程个数,并提供了同步机制。使用Semaphore(信号量)的主要两个目的,一个是用于多个共享资源的相互排斥使用,另一个用于并发资源数的控制.
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class SemaphoreDemo {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3);
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 号车停了三秒走了");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
}
},String.valueOf(i)).start();
}
}
}
###输出的随机结果
1 号车抢到了停车位
3 号车抢到了停车位
2 号车抢到了停车位
2 号车停了三秒走了
3 号车停了三秒走了
4 号车抢到了停车位
1 号车停了三秒走了
5 号车抢到了停车位
6 号车抢到了停车位
6 号车停了三秒走了
4 号车停了三秒走了
5 号车停了三秒走了
Process finished with exit code 0