【Java进阶】线程池之参数介绍、拒绝策略、有限队列线程池,使用ThreadPoolTaskExecutor进行介绍

总共有四种拒绝策略,实际线程数量超过线程池设定的数量,将会启用拒绝策略
1. AbortPolicy(默认拒绝策略): 实际线程数量大于维护队列中设定的数量,将会触发拒绝任务的处理程序,它将抛出RejectedExecutionException
2. DiscardPolicy: 实际线程数量大于维护队列中设定的数量,将会被静默丢弃
3. DiscardOldestPolicy: 实际线程数量大于维护队列中设定的数量,将会把队列中最老的线程静默丢弃,把新的放进来
4. CallerRunsPolicy: 实际线程数量大于维护队列中设定的数量,多出来的线程由调用线程(主线程)处理

 

推荐使用ThreadPoolTaskExecutor创建线程池

@Configuration
public class ThreadPoolConfig {

    @Bean(name = "testThreadPool")
    public ThreadPoolTaskExecutor createPool(){
        ThreadPoolTaskExecutor poolTaskExecutor = new ThreadPoolTaskExecutor();
        //线程池所使用的缓冲队列
        poolTaskExecutor.setQueueCapacity(60);
        //线程池维护线程的最少数量
        poolTaskExecutor.setCorePoolSize(3);
        //线程池维护线程的最大数量
        poolTaskExecutor.setMaxPoolSize(5);
        //线程前缀名称
        poolTaskExecutor.setThreadNamePrefix("testThreadPool");

        /**
         * 总共有四种拒绝策略,实际线程数量超过线程池设定的数量,将会启用拒绝策略
         * 1. AbortPolicy(默认拒绝策略): 实际线程数量大于维护队列中设定的数量,将会触发拒绝任务的处理程序,它将抛出RejectedExecutionException
         * 2. DiscardPolicy: 实际线程数量大于维护队列中设定的数量,将会被静默丢弃
         * 3. DiscardOldestPolicy: 实际线程数量大于维护队列中设定的数量,将会把队列中最老的线程静默丢弃,把新的放进来
         * 4. CallerRunsPolicy: 实际线程数量大于维护队列中设定的数量,多出来的线程由调用线程(主线程)处理
         */
        poolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

        //默认是60s,线程池中启用的线程,空闲时间超过这个时间就会被销毁
        poolTaskExecutor.setKeepAliveSeconds(60);
        poolTaskExecutor.initialize();
        return poolTaskExecutor;
    }
}

CallerRunsPolicy这个拒绝策略不好理解,测试用例如下(说白了就是:所有线程都会被执行,从干不过来了,主帮忙干)

public static void main(String[] args) {
    ThreadPoolTaskExecutor poolTaskExecutor = new ThreadPoolTaskExecutor();
    poolTaskExecutor.setQueueCapacity(5);
    poolTaskExecutor.setCorePoolSize(3);
    poolTaskExecutor.setMaxPoolSize(5);
    poolTaskExecutor.setThreadNamePrefix("callerRunsPolicyTest");
    poolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    poolTaskExecutor.setKeepAliveSeconds(60);
    poolTaskExecutor.initialize();

    long start = System.currentTimeMillis();
    for (int i = 0; i < 20; i++) {
        poolTaskExecutor.submit(() -> {
            try {
                System.out.println(Thread.currentThread().getName() + ":执行任务");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }
    long end = System.currentTimeMillis();
    System.out.println("主线程完成任务,耗时:" + (end - start)/1000 + "秒,主线程名为:" + Thread.currentThread().getName());
}

输出结果:

callerRunsPolicyTest2:执行任务
callerRunsPolicyTest3:执行任务
callerRunsPolicyTest1:执行任务
callerRunsPolicyTest4:执行任务
main:执行任务
callerRunsPolicyTest5:执行任务
main:执行任务
callerRunsPolicyTest1:执行任务
callerRunsPolicyTest5:执行任务
callerRunsPolicyTest2:执行任务
callerRunsPolicyTest3:执行任务
callerRunsPolicyTest4:执行任务
callerRunsPolicyTest4:执行任务
callerRunsPolicyTest5:执行任务
callerRunsPolicyTest3:执行任务
callerRunsPolicyTest2:执行任务
主线程完成任务,耗时:2秒,主线程名为:main
callerRunsPolicyTest1:执行任务
callerRunsPolicyTest2:执行任务
callerRunsPolicyTest3:执行任务
callerRunsPolicyTest1:执行任务

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值