SpringBoot_JUC工具使用

前言

记录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[倒计时器]

用来进行线程同步协作,等待所有线程完成倒计时.

场景

  1. 同步等待多个线程执行完毕()
  2. 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值