ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java多线程实现方式(四)

2022-01-08 19:02:51  阅读:164  来源: 互联网

标签:java 方式 corePoolSize 创建 任务 线程 executor 多线程


    hello,伙伴们,我们继续java多线程实现方式的学习,本节中我们通过线程池来实现多线程。那为什么使用线程池呢?使用线程池的好处是减少在创建和销毁线程上所花的时间以及系统资源的开销,解决资源不足的问题。如果不使用线程池,有可能造成系统创建大量同类线程而导致消耗完内存或者 “过度切换”的问题。在阿里开发手册中明确线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,这样的处理方式让开发的同学更加明确线程池的运行规则,规避资源耗尽的风险。那么我们接下来创建一个线程池实际用一下:

@Configuration
@EnableAsync
public class ThreadPoolTaskConfig {
    /**
     *  默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,
     *  当线程池中线程数未达到corePoolSize时,每来一个任务就会创建一个线程来执行 即使线程池中有空闲的线程,
     *	当线程池中的线程数目达到corePoolSize并且缓存队列未满,就会把到达的任务放到缓存队列当中;
     *  当缓存队列满了,就继续创建线程来执行新来的任务,当线程数量大于等于maxPoolSize后,开始使用拒绝策略拒绝
     */
    /** 核心线程数 */
    private static final int corePoolSize = 6;
    /** 最大线程数 */
    private static final int maxPoolSize = 12;
    /** 允许线程空闲时间(单位:默认为秒) */
    private static final int keepAliveTime = 10;
    /** 缓冲队列大小 */
    private static final int queueCapacity = 10;
    @Bean("taskExecutor") 
    public ThreadPoolTaskExecutor taskExecutor(){
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(corePoolSize);
        executor.setMaxPoolSize(maxPoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setKeepAliveSeconds(keepAliveTime);
        //线程池对拒绝任务的处理策略, CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 初始化
        executor.initialize();
        return executor;
    }
}

接下来我们在需要执行多线程的地方使用该线程池:

/**
     * 异步添加操作日志记录
     */
    @Async("taskExecutor")(开启异步执行 并通过“taskExecutor”来
   指定使用我们创建的线程池中线程异步执行)
    public void addLogRecord(){
        LogRecord logRecord = new LogRecord();
        // 省略 日志记录业务逻辑
        logRecordRepository.save(logRecord);
    }

小总结:当我们通过定义线程池来实现多线程时,每当有任务提交过来判断逻辑,线程池中线程数和 corePoolSize大小关系–> workQueue是否已满 –>线程池中线程数和 maximumPoolSize大小关系。当线程池中线程数>=maximumPoolSize时,接下来要执行用户自定义的任务拒绝策略,任务拒绝策略一共有下面四种:

AbortPolicy:直接抛出异常,这是默认策略;

CallerRunsPolicy:用调用者所在的线程来执行任务;

DiscardOldestPolicy:丢弃阻塞队列中最靠前的任务,并执行当前任务;

DiscardPolicy:直接丢弃任务;以上就是通过线程池实现多线程的使用。

伙伴们,我们下期见!

标签:java,方式,corePoolSize,创建,任务,线程,executor,多线程
来源: https://blog.csdn.net/hardworking_Man/article/details/122351111

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有