若依线程池理解及实际使用

一直想知道线程池是如何使用的,从网上查阅了大量的资料,接下来就按照我自己的理解整理一下若依线程池的使用。

线程池的使用场景

高并发场景,例如秒杀商品,当秒杀商品使用的是单线程,那么所耗费的时间可想而知。小编在这里想了几个技术栈来解决秒杀商品,包括使用线程池(比单线程时间要快很多,不用频繁的创建线程,关闭线程,因为池子里面有创建好的线程,直接使用就可以)、redis分布式锁、rabbitmq异步处理具体业务。具体例子(你的商城网站,这次要有10件商品进行秒杀,假设每件商品的抢购人数是一万人,那么1秒你的接口接收到的请求就是10万次,这个就属于高并发,首先你的代码应该是接收到请求,用线程池处理这么多的请求,这里就节约了很多时间,然后根据每个商品的ID加分布式锁,确保商品没有超卖,然后就是rabbitmq去异步处理扣减库存和生成订单等等)小编这里只举例一个最常见的场景,剩余的场景还有很多。

若依线程池的配置

相信很多小伙伴看到上面线程池的使用场景,也对线程池的重要性有了深刻的了解,那么下面来看一下若依的线程池的配置

若依是在项目启动的时候,就把线程池注入到spring容器中,主要涉及到两个线程池的使用,如图:

用到最多的就是第一张图,里面代码的意思其实就是配置线程的核心数量、最大数量、空闲时间、拒绝策略,这里不过多介绍,下面直接教大家如何使用。

若依线程池的使用

//获得线程池

private ThreadPoolTaskExecutor executor = SpringUtils.getBean("threadPoolTaskExecutor");

//把业务放到线程池里面执行
executor.submit(processSeckill(String productId, String userId) );

//主要业务
@Async("seckillTaskExecutor")
    public void processSeckill(String productId, String userId) {
        String lockKey = "seckill_lock:" + productId;
        String requestId = IdUtils.fastSimpleUUID();
        int expireTime = 10; // 锁的过期时间(秒)

        try {
            if (redisLockService.acquireLock(lockKey, requestId, expireTime)) {
                try {
                    // 开启事务管理
                    DefaultTransactionDefinition def = new DefaultTransactionDefinition();
                    def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
                    TransactionStatus status = txManager.getTransaction(def);

                    try {
                        // 查询商品库存
                        ShopProduct product = shopProductService.selectShopProduct(productId);
                        if (product == null || product.getStock() <= 0) {
                            LOG.error("商品ID={} 库存不足", productId);
                            return;
                        }

                        // 减少库存
                        product.setStock(product.getStock() - 1);
                        shopProductService.updateShopProduct(product);

                        // 记录订单(假设有一个订单服务)
                        // orderService.createOrder(productId, userId);

                        txManager.commit(status);
                        LOG.info("用户ID={} 成功秒杀商品ID={}", userId, productId);
                    } catch (Exception e) {
                        txManager.rollback(status);
                        LOG.error("秒杀失败: 商品ID={}, 用户ID={}", productId, userId, e);
                    }
                } finally {
                    redisLockService.releaseLock(lockKey, requestId);
                }
            } else {
                LOG.error("获取锁失败,秒杀请求失败: 商品ID={}, 用户ID={}", productId, userId);
            }
        } catch (Exception e) {
            LOG.error("处理秒杀请求异常: 商品ID={}, 用户ID={}", productId, userId, e);
        }
    }

结尾

对于线程池来说,作者也只是小白,底层代码在这里我也没有列出来,想了解底层代码的可以再去看一眼其他大神的笔记,同时以上所有内容仅供参考,有什么问题尽管提出来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值