线程池实践记录

背景 

最近遇到了一个业务,需要做个并发处理 没想到遇到了很大的乌龙 还好没上线 最后改为下游提供批量接口

案例一 

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = newFixedThreadPool(5);
        ArrayList<Integer> objects = new ArrayList<>();
        ArrayList<Callable<Integer>> threadList = new ArrayList<>();
        AtomicInteger batchNum = new AtomicInteger(1);

        for (int i = 0; i < 10; i++) {
            // 幂等id
            Future<Integer> future = null;
            try {
                System.out.println("提交一个"+batchNum.get()+"线程");
                future = executorService.submit(new Callable<Integer>() {
                    @Override
                    public Integer call() throws Exception {
                        Thread.sleep(2000);
                        System.out.println("第"+batchNum.get()+"次执行");
                        System.out.println("线程执行:"+ batchNum.getAndIncrement());
                        return batchNum.get() ;
                    }
                });
                if (future != null) {
                    objects.add(future.get());
                }
            } catch (Exception e) {
                LoggerUtil.warn(LOGGER, e, "id:{0},exception:{1}", batchNum.get(), e.getMessage());
            }
        }
//        List<Future<Integer>> futures = executorService.invokeAll(threadList);
        executorService.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                System.out.println("提交一个"+batchNum.get()+"线程");

                Thread.sleep(10000);
                System.out.println("第"+batchNum.get()+"次执行");
                System.out.println("线程执行:"+ batchNum.getAndIncrement());
                return batchNum.get() ;
            }
        });
        executorService.shutdown();
        System.out.println(executorService.isShutdown());
//        executorService.shutdown();
        System.out.println("aaaaa");
    }

错误1

预期 提交10个线程 并发执行

循环创建线程 会阻塞代码 会等到线程执行完 才会执行下一个线程

错误2

预期 executorService.shutdown(); 会阻塞等待线程执行完 才会关闭线程池 在执行后面代码

实际 直接关闭线程池 不阻塞代码 但线程还是会继续执行,业务不统一

贴下运行效果

网上查了资料后 修改后代码

修复案例

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = newFixedThreadPool(5);
        ArrayList<Callable<Integer>> threadList = new ArrayList<>();
        AtomicInteger batchNum = new AtomicInteger(1);
        for (int i = 0; i < 10; i++) {
            // 幂等id
            try {
                System.out.println("提交一个"+batchNum.get()+"线程");
                threadList.add(() ->{
                    Thread.sleep(2000);
                    System.out.println("线程执行:"+ batchNum.getAndIncrement());
                    return batchNum.get() ;
                });
            } catch (Exception e) {
                LoggerUtil.warn(LOGGER, e, "id:{0},exception:{1}", batchNum.get(), e.getMessage());
            }
        }
       List<Future<Integer>> futures = executorService.invokeAll(threadList);
        executorService.shutdown();
        System.out.println(executorService.isShutdown());
        System.out.println("aaaaa");
    }

这样和预期结果 比较符合了 但是线程池创建不太友好  这里贴下

            <bean
                    class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
                <property name="corePoolSize" value="10"/>
                <property name="keepAliveSeconds" value="60"/>
                <property name="maxPoolSize" value="15"/>
                <!-- 线程池缓冲队列中长度,这里设置为5,按照FIFO规则 -->
                <property name="queueCapacity" value="500"/>
                <property name="threadNamePrefix" value="asynExecutor"/>
            </bean>

如有不足 欢迎指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值