文章目录
前言
记录springboot项目环境下JUC工具的使用场景
Semaphore[信号量]
信号量,用来限制能同时访问共享资源的线程上限
示例–控制耗时任务执行的线程数
/**
* 控制耗时任务执行的线程数
*/
@Api(tags = "Semaphore测试")
@RestController
@RequestMapping("/semaphore/test")
public class SemaphoreTestController {
private static final Logger LOGGER = LoggerFactory.getLogger(SemaphoreTestController.class);
@Autowired
private ThreadPoolTaskExecutor taskExecutor;
private Semaphore semaphore = new Semaphore(3);
@PostMapping("/doTask")
public ApiResult<String> test() {
if (semaphore.availablePermits() == 0) {
LOGGER.info("当前任务繁忙,请求拒绝!");
return new ApiResult<>("当前任务繁忙,请求拒绝!");
}
taskExecutor.execute(() -> {
try {
semaphore.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
LOGGER.info("执行任务");
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
}
});
return new ApiResult<>(MessageFormat.format("剩余{0}信号量" , semaphore.availablePermits() -1));
}
}
- void acquire():从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。
- void release():释放一个许可,将其返回给信号量。
- int availablePermits():返回此信号量中当前可用的许可数。
- boolean hasQueuedThreads():查询是否有线程正在等待获取
CountDownLatch[倒计时器]
用来进行线程同步协作,等待所有线程完成倒计时.
场景
- 同步等待多个线程执行完毕()
- spring容器启动后加载权限,加载缓存数据, 实现数据预热
示例–并发加载缓存
/**
* 使用CountDownLatch并发加载不同的缓存数据(增加启动后缓存的加载速度)
*/
@Component
public class InitCacheApplicationRunner implements ApplicationRunner {
private static final Logger LOGGER = LoggerFactory.getLogger(InitCacheApplicationRunner.class);
@Resource
private ThreadPoolTaskExecutor taskExecutor;
@Override
public void run(ApplicationArguments args) throws Exception {
LOGGER.info("缓存预热--开始");
CountDownLatch latch = new CountDownLatch(2);
taskExecutor.execute(() -> {
try {
// 模拟缓存预热任务
TimeUnit.SECONDS.sleep(5);
LOGGER.info("缓存预热任务01");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
latch.countDown();
}
});
taskExecutor.execute(() -> {
try {
TimeUnit.SECONDS.sleep(10);
LOGGER.info("缓存预热任务02");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
latch.countDown();
}
});
latch.await();
LOGGER.info("缓存预热--完毕");
}
}
注意 CyclicBarrier 与 CountDownLatch 的主要区别在于 CyclicBarrier 是可以重用的 CyclicBarrier 可以被比
喻为『人满发车』
cyclicBarrier[循环屏障]
cyclicBarrier 循环屏障
示例–excel 多个sheel计算后汇总
TODO