springboot集成线程池,自定义线程池与工厂

根据开发规范不太建议我们自己去创建线程,毕竟创建与销毁都是一种损耗。

JDK也提供了几种默认的线程池,这些要么就是最大线程数基本没上限,要么就是阻塞队列没有上限,如果代码有问题很容易造成OOM。所以我们来自己实现一个线程池。

springboot集成线程池(超简单四步即成)
  1. 定义一个线程池:线程池的7大参数可以参考我的上一篇博客。这里我自定义了一个线程工厂类,来制定一个有意义的线程名称,方便出错时回溯。
@Configuration
public class ExecutorServiceConfig {

    private Integer corePoolSize = 8;
    private Integer maximumPoolSize = 80;
    private Long keepAliveTime = 1L;

    @Bean
    public Executor executorService() {

        int cpuNums = Runtime.getRuntime().availableProcessors();
        if (cpuNums > corePoolSize) {
            maximumPoolSize = cpuNums;
        }

        return new ThreadPoolExecutor(corePoolSize,
                (int) (maximumPoolSize / (1 - 0.9)),
                keepAliveTime,
                TimeUnit.SECONDS, new SynchronousQueue<>(),
                new UserThreadFactory("osCreatePool"),
                new ThreadPoolExecutor.AbortPolicy());
    }

}
  1. 自定义线程工厂类:更改了一下线程池的名称
public class UserThreadFactory implements ThreadFactory {
    private final AtomicInteger threadNumber = new AtomicInteger(1);
    private final String namePrefix;

    UserThreadFactory(String poolName) {
        namePrefix = "This thread is from UserThreadFactory's " + poolName + "-thread-";
    }

    @Override
    public Thread newThread(Runnable task) {
        Thread t = new Thread(null, task,
                namePrefix + threadNumber.getAndIncrement(),
                0);
        if (t.isDaemon())
            t.setDaemon(false);
        if (t.getPriority() != Thread.NORM_PRIORITY)
            t.setPriority(Thread.NORM_PRIORITY);
        return t;
    }
}
  1. 定义异步执行接口
@Service
public class AsyncTestServiceImpl implements AsyncTestService {

    @Override
    @Async("executorService")
    public void doTest() {
        System.out.println(Thread.currentThread().getName() + "执行了");

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(Thread.currentThread().getName() + "结束执行了");
    }
}
  1. 开启异步支持:@EnableAsync在启动类或者配置类上均可
注意事项(常见异步变同步的原因)
  • 在同一个类下的方法中调用其另一个异步方法,异步会变成同步。因为异步注解@Async本质就是spring通过AOP对方法的增强。被增强的时候使用的是动态代理对象去调用方法。如果在同一个类中方法互调属于内部this调用,不会有增强的效果。失去异步的效果,如果有这种需求,自行使用其动态代理对象去调用。
  • 由于线程池的扩容发生在corepoolsize与阻塞队列都满了的情况下才会扩容到max。如果我们阻塞队列的值给的很大,corepoolsize的初始值给的很小比如1。这样异步任务都进入到阻塞队列中,并不会开多个线程去执行,失去异步效果。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值