前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ThreadPoolExecutor线程池实战

ThreadPoolExecutor线程池实战

作者头像
关忆北.
发布2021-12-07 16:43:17
4630
发布2021-12-07 16:43:17
举报
文章被收录于专栏:关忆北.关忆北.关忆北.

ThreadPoolExecutor线程池实战

Demo已开源至Github,threadDemo

1.配置TreadPoolProperty

ThreadPoolTaskExecutor构造方法:
ThreadPoolExecutor(int corePoolSize,
                        int maximumPoolSize,
                        long keepAliveTime,
                        TimeUnit unit,
                        BlockingQueue<Runnable> workQueue,
                        ThreadFactory threadFactory,
                        RejectedExecutionHandler handler)
在这里插入图片描述
在这里插入图片描述

为方便全局使用自定义线程池ThreadPoolTaskExecutor,我们建议使用将其初始化所需参数写入到yml/application配置文件中,以达到不入侵源码且改动线程池运行参数的目的。本文将使用 @ConfigurationProperties注解读取yml配置的方式初始化线程池构造方法。如对获取yml有疑问,可以查看我的另一篇文章,专门讲述了如何获取yml里配置的数据。当然如果您用做demo个人练习,也可以使用赋值的方式完成。

文章链接:如何获取yml里的配置数据?

构造方法参数
  • corePoolSize:核心线程数,一般取CPU物理核心数,线程默认一直存活
  • maximumPoolSize:最大容纳线程数,一般取核心线程数的2倍
  • keepAliveTime:非核心线程的闲置超时时间
  • unit:keepAliveTime闲置时间单位,一般取秒
  • queueCapacity:工作队列长度
  • awaitTerminationSeconds:设置此执行程序应该在关闭时阻止的最大秒数
  • threadNamePrefix:线程前缀名
  • RejectedExecutionHandler:线程池内阻塞队列已满,无法接受任务的拒绝策略

SpringThreadPoolPropertyConfig.class配置类

@ConfigurationProperties(prefix = "threadpool.property")
public class SpringThreadPoolPropertyConfig {

    private Integer corePoolSize;

    private Integer maxPoolSize;

    private Integer keepAliveSeconds;

    private Integer queueCapacity;

    private Integer awaitTerminationSeconds;

    private String threadNamePrefix;

    private Boolean waitForTasksToCompleteOnShutdown;
}

application.yml

threadpool:
  property:
    corePoolSize: 6
    maxPoolSize: 12
    keepAliveSeconds: 10
    queueCapacity: 1000
    awaitTerminationSeconds: 0
    threadNamePrefix: pool_
    waitForTasksToCompleteOnShutdown: true

SpringThreadPoolConfig.class线程池配置类

@Configuration
@EnableAsync
public class SpringThreadPoolConfig {

    @Autowired
    private SpringThreadPoolPropertyConfig threadPoolConfig;

    @Bean("taskExecutor")
    public TaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor customizeThreadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        customizeThreadPoolTaskExecutor.setCorePoolSize(threadPoolConfig.getCorePoolSize());
        customizeThreadPoolTaskExecutor.setMaxPoolSize(threadPoolConfig.getMaxPoolSize());
        customizeThreadPoolTaskExecutor.setKeepAliveSeconds(threadPoolConfig.getKeepAliveSeconds());
        customizeThreadPoolTaskExecutor.setQueueCapacity(threadPoolConfig.getQueueCapacity());
        customizeThreadPoolTaskExecutor.setAwaitTerminationSeconds(threadPoolConfig.getAwaitTerminationSeconds());
        customizeThreadPoolTaskExecutor.setThreadNamePrefix(threadPoolConfig.getThreadNamePrefix());
        customizeThreadPoolTaskExecutor.setWaitForTasksToCompleteOnShutdown(threadPoolConfig.getWaitForTasksToCompleteOnShutdown());
        customizeThreadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return customizeThreadPoolTaskExecutor;
    }
}

配置完成


使用线程池

@Resource(name = "taskExecutor")

@Slf4j
@Service
public class AsyncServiceImpl implements AsyncService {

    @Resource(name = "taskExecutor")
    private ThreadPoolTaskExecutor taskExecutor;

    @Override
    public void processingTimeOperation() {

        /**
         *
         * 在此处理耗时操作业务逻辑,
         * 如数据量大的插入,只需要在业务层将List等段截取后的List在for循环中传入每一个List调用异步线程即可
         */
        try {
            log.info("进入异步");
            int activeCount = taskExecutor.getActiveCount();
            taskExecutor.submit(() -> log.info(String.valueOf(activeCount))).get();
            log.debug("当前线程信息:-{}", taskExecutor.getThreadNamePrefix() + taskExecutor.getActiveCount());
            log.info("异步体执行完成");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

taskExecutor.submit()中执行异步耗时操作,如大批量插入操作,submit()方法可以返回线程执行结果,无返回值的需求可以使用execute()方法。

注意事项:

1.异步操作相关逻辑需要单独在一个接口和实现类中完成。 2.@Async注解要使用在主线程的业务方法中,如果使用在处理耗时操作的逻辑中,会出现主线程完毕,不走子线程异步代码的问题。 具体可以参考上文Github地址中源码 本文涉及到自定义线程池理论知识部分请查看我的另一篇文章: 自定义线程池理论知识部分

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-06-06 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ThreadPoolExecutor线程池实战
    • 1.配置TreadPoolProperty
      • 使用线程池
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档