Semaphore
信号量,可以理解为申请通行证,通行证的个数是有限了,要是申请完了则不可能申请成功并执行逻辑,但是申请后,等程序执行完毕就可以释放通行证,具体代码示例如下:
package com.bdcloud.threadpool;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
/***
* 信号量Demo
*/
public class SemaphoreDemo {
public static void main(String[] args) {
//定义同行证,并设置总个数为2
Semaphore semaphore = new Semaphore(2);
ExecutorService executorService = Executors.newFixedThreadPool(4);
for (int i = 0; i < 3; i++) {
executorService.submit(new Runnable() {
@Override
public void run() {
//尝试申请通行证,要是申请成功则执行
if (semaphore.tryAcquire()){
System.out.println(Thread.currentThread().getName()+"申请成功,并可以执行");
//释放信号量
semaphore.release();
}
}
});
}
executorService.shutdown();
}
}
//执行结果如下
Connected to the target VM, address: '127.0.0.1:59985', transport: 'socket'
Disconnected from the target VM, address: '127.0.0.1:59985', transport: 'socket'
pool-1-thread-3申请成功,并可以执行
pool-1-thread-1申请成功,并可以执行
pool-1-thread-2申请成功,并可以执行
Process finished with exit code 0
CyclicBarrier
其类似于在比赛中会等待所有的赛车手准备完毕后才会一起开始比赛,代码结构中则为在系统中的一组线程要互相等待其他线程达到某一状态并一起执行,例子如下:
package com.bdcloud.threadpool;
import java.util.concurrent.*;
/***
* CyclicBarrier 尝试在赛车场景,等多个赛车手都准备ok后在开始比赛
*/
public class CyclicBarrierDemo {
/***
* 赛车手对象
*/
public static class CarDriver implements Runnable{
private String name;
private CyclicBarrier cyclicBarrier;
public CarDriver(String name,CyclicBarrier cyclicBarrier){
this.name = name;
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
//执行准备工作
try {
Thread.sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name+" is Ready");
try {
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println(name+" go......");
}
}
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
ExecutorService executorService = Executors.newFixedThreadPool(3);
executorService.submit(new CarDriver("张三",cyclicBarrier));
executorService.submit(new CarDriver("李四",cyclicBarrier));
executorService.submit(new CarDriver("王五",cyclicBarrier));
executorService.shutdown();
}
}
//执行结果如下:
Connected to the target VM, address: '127.0.0.1:60311', transport: 'socket'
张三 is Ready
王五 is Ready
李四 is Ready
李四 go......
王五 go......
张三 go......
CountDownLaunch
计数器等待,每一个任务执行完毕计数器减去1,知道为0的时候主线程继续执行,模拟场景为系统启动时候会需要依赖其他子系统,等其他子系统初始化完毕后系统才会继续执行,代码如下:
package com.bdcloud.threadpool;
import java.util.concurrent.*;
/***
* 模拟后台启动的时候会进行各种初始化操作,等所有初始化操作完成之后才可以正常启动
*/
public class CountDownLaunchDemo {
public static class InitWorker implements Runnable{
private String name;
private CountDownLatch countDownLatch;
public InitWorker(String name,CountDownLatch countDownLatch){
this.name = name;
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
countDownLatch.countDown();
System.out.println(name+" 已经完成初始化--------");
}
}
public static void main(String[] args) {
CountDownLatch countDownLatch = new CountDownLatch(3);
ExecutorService executorService = Executors.newFixedThreadPool(3);
System.out.println("系统启动。。。。。。。。。。。。。。");
executorService.submit(new InitWorker("数据库",countDownLatch));
executorService.submit(new InitWorker("redis", countDownLatch));
executorService.submit(new InitWorker("InfluxDb", countDownLatch));
try {
//等待各线程异步执行初始化完成
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("各个子系统启动完毕。。。。。。。系统继续执行");
//关闭线程池
executorService.shutdown();
}
}
//代码例子如下:
Connected to the target VM, address: '127.0.0.1:60341', transport: 'socket'
系统启动。。。。。。。。。。。。。。
Disconnected from the target VM, address: '127.0.0.1:60341', transport: 'socket'
数据库 已经完成初始化--------
InfluxDb 已经完成初始化--------
redis 已经完成初始化--------
各个子系统启动完毕。。。。。。。系统继续执行