Springboot结合线程池使用Scheduled

定义线程池

@Configuration
public class AlertThreadPoolExecutor  {

    @Bean(name = "AlertExecutorService")
    public ExecutorService getExecutorService(){
        int corePoolSize = 2;  //核心线程数
        int maximumPoolSize = 4; //最大线程数
        long keepAliveTime = 10; //救急线程空闲存活时间
        TimeUnit unit = TimeUnit.SECONDS; //单位时间
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(2); //阻塞队列
        ThreadFactory threadFactory = new NameTreadFactory(); //线程工程
        RejectedExecutionHandler handler = new MyIgnorePolicy(); //拒绝策略
        ThreadPoolExecutor executor  = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit,
                workQueue, threadFactory, handler);

        return executor ;
    }

    /**
     * 线程工程
     */
    static class NameTreadFactory implements ThreadFactory {

        private final AtomicInteger s = new AtomicInteger(1);

        @Override
        public Thread newThread(Runnable r) {
            Thread t = new Thread(r, "Alert-thread-" + s.getAndIncrement());
            System.out.println(t.getName() + " has been created");
            return t;
        }
    }

    /**
     * 拒绝策略
     */
    public static class MyIgnorePolicy implements RejectedExecutionHandler {

        public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
            doLog(r, e);
        }

        private void doLog(Runnable r, ThreadPoolExecutor e) {
            // 可做日志记录等
            System.err.println( r.toString() + " rejected");
//          System.out.println("completedTaskCount: " + e.getCompletedTaskCount());
        }
    }
}

task任务
先开启异步
在这里插入图片描述
在这里插入图片描述

如何设置参数
需要根据几个值来决定

tasks :每秒的任务数,假设为500~1000

taskcost:每个任务花费时间,假设为0.1s

responsetime:系统允许容忍的最大响应时间,假设为1s

做几个计算

corePoolSize = 每秒需要多少个线程处理?

threadcount = tasks/(1/taskcost) = tasks*taskcout = (500 ~ 1000)*0.1 = 50~100 个线程。

corePoolSize设置应该大于50。

根据8020原则,如果80%的每秒任务数小于800,那么corePoolSize设置为80即可。

queueCapacity = (coreSizePool/taskcost)*responsetime

计算可得 queueCapacity = 80/0.1*1 = 800。意思是队列里的线程可以等待1s,超过了的需要新开线程来执行。

切记不能设置为Integer.MAX_VALUE,这样队列会很大,线程数只会保持在corePoolSize大小,当任务陡增时,不能新开线程来执行,响应时间会随之陡增。

maxPoolSize 最大线程数在生产环境上我们往往设置成corePoolSize一样,这样可以减少在处理过程中创建线程的开销。

rejectedExecutionHandler:根据具体情况来决定,任务不重要可丢弃,任务重要则要利用一些缓冲机制来处理。

keepAliveTime和allowCoreThreadTimeout采用默认通常能满足。

以上都是理想值,实际情况下要根据机器性能来决定。如果在未达到最大线程数的情况机器cpu load已经满了,则需要通过升级硬件和优化代码,降低taskcost来处理。 如何设置参数来源于该文章点击查看

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot使用Scheduled注解来执行定时任务时,默认是使用单线程来执行任务的,如果有多个任务同时执行,就会出现任务阻塞的情况。为了避免这种情况,我们可以配置Scheduled线程池来执行任务。 在Spring Boot中,我们可以通过在@Configuration注解的类中定义一个ScheduledExecutorService类型的bean来实现Scheduled线程池的配置,如下所示: ```java @Configuration public class ScheduledConfig { @Bean(destroyMethod="shutdown") public ScheduledExecutorService scheduledExecutorService() { return Executors.newScheduledThreadPool(5); } } ``` 上述代码中,我们定义了一个ScheduledExecutorService类型的bean,使用newScheduledThreadPool方法创建了一个大小为5的线程池,并通过destroyMethod指定了当应用关闭时销毁线程池。 接下来,我们可以在需要执行定时任务的方法上添加@Scheduled注解,并指定cron表达式,如下所示: ```java @Component public class ScheduledTask { @Scheduled(cron = "0 0/1 * * * ?") public void task1() { // 任务1的业务逻辑 } @Scheduled(cron = "0 0/2 * * * ?") public void task2() { // 任务2的业务逻辑 } } ``` 上述代码中,我们在ScheduledTask类中定义了两个方法,分别用@Scheduled注解指定了cron表达式,这样就可以在应用启动后按照指定的时间间隔执行任务了。需要注意的是,我们不需要手动启动线程池Spring Boot会自动将ScheduledExecutorService类型的bean注入到@Scheduled注解的方法中,并使用线程池来执行任务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值