介绍
对线程的等待机制进行优化,还是同样的例子
前几天我去买正新鸡排,买一个鸡排送一杯饮料,在炸鸡排的同时,可以调制装配饮料,因此,可以将这两个操作并行,当两个操作执行完,进行包装完成售出
如果有多个人进行购买,那么以上操作就有了优化的空间。可以使用线程池将线程的重复创建优化掉。但是为了减少重复创建,就要保证线程不销毁,那么就无法使用 join() 来完成,因此引入了新的等待机制 CountDownLatch 与 CyclicBarrier。这个等待机制的原理就是利用计数器,给计数器设置一个初始值,每完成一个等待操作,计数器值就-1,当计数器值为0时,等待结束,继续执行。CountDownLatch 与 CyclicBarrier不同的是,当计数器值为0时,如果需要继续这个等待行为,CountDownLatch 需要手动重新设置计数器初始值,而 CyclicBarrier 则是当计数器值为0时,调用处理机制,然后重新将计数器值恢复为初始值
使用
package cn.zjm404.stu.thread.cooperation.wait.pool;
import java.util.concurrent.*;
public class ZhengXinChickenChopShop {
private ThreadPoolExecutor tp;
public ZhengXinChickenChopShop(ThreadPoolExecutor tp){
this.tp = tp;
}
private void getDrink(){
System.out.println("配置饮料");
}
private void getChickenChop(){
System.out.println("炸鸡排");
}
/**
* 使用 CountDownLatch
*/
public void sellChickenChop1(){
CountDownLatch ctl = new CountDownLatch(2);
tp.execute(()->{
getDrink();
ctl.countDown();
});
tp.execute(()->{
getChickenChop();
ctl.countDown();
});
try {
ctl.await();
} catch (InterruptedException e) {
Thread.currentThread().isInterrupted();
e.printStackTrace();
}
System.out.println("打包,售出");
}
/**
* 使用 CyclicBarrier
*/
public void sellChickenChop2(){
CyclicBarrier cb = new CyclicBarrier(2,()->{
System.out.println("打包,售出");
});
tp.execute(()->{
getDrink();
try {
cb.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
});
tp.execute(()->{
getChickenChop();
try {
cb.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
});
}
}
public class Client {
public static void main(String[] args){
ThreadPoolExecutor poolExecutor = (ThreadPoolExecutor) Executors.newFixedThreadPool(3);
ZhengXinChickenChopShop shop = new ZhengXinChickenChopShop(poolExecutor);
shop.sellChickenChop2();
poolExecutor.shutdown();
}
}