springboot单类集中定义线程池

简介: 该内容是关于Spring中异步任务的配置和使用步骤。首先,在启动类添加`@EnableAsync`注解开启异步支持。然后,自定义线程池类`EventThreadPool`,设置核心和最大线程数、存活时间等参数。接着,将线程池bean注入到Spring中,如`@Bean("RewardThreadPool")`。最后,在需要异步执行的方法上使用`@Async`注解,例如在一个定时任务类中,使用`@Scheduled(cron = "...")`和`@Async`结合实现异步定时任务。

 1、在启动类上加注解  @EnableAsync

2、定义线程池的类

package com.javabase.Thread;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.concurrent.*;
public class EventThreadPool extends ThreadPoolExecutor {
    /**
     * 定义线程工厂名称
     */
    private static ThreadFactory HANDLEREMINDWAY_FACTORY = new ThreadFactoryBuilder()
            .setNameFormat("EventThreadPool-%d").build();
    public EventThreadPool() {
        super(Runtime.getRuntime().availableProcessors(), Runtime.getRuntime().availableProcessors() * 30,
                20, TimeUnit.SECONDS, new ArrayBlockingQueue<>(1000), HANDLEREMINDWAY_FACTORY,new CallerRunsPolicy());
    }
//    public ThreadPoolExecutor getThreadPoolExecutor() {
//        return new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(), Runtime.getRuntime().availableProcessors() * 30,
//            20, TimeUnit.SECONDS, new ArrayBlockingQueue<>(1000));
//    }
    public EventThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime) {
        /**
         *
         * (ArrayBlockingQueue读写只有一个锁(效率更高),LinkedBlockingQueue读写锁分离)
         * LinkedBlockingQueue即无界队列.
         * 将ArrayBlockingQueue即无界队列的大小设置为1000.
         * 使用无界队列
         * 将LinkedBlockingQueue即无界队列的大小设置为500.
         * 将导致在所有 corePoolSize线程都忙的情况下将新任务加入队列,
         * 这样,创建的线程就不会超过 corePoolSize, 而且当排队的任务超过500时,将拒绝执行
         */
        super(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1000), Executors
                .defaultThreadFactory());
    }
}

image.gif

3、注入工厂到spring中

package com.javabase.Thread;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
public class ThreadPoolConfig {
    @Bean("RewardThreadPool")
    public ThreadPoolExecutor rewardThreadPool() {
        return new EventThreadPool();
    }
    @Bean("reportThreadPool")
    public ThreadPoolExecutor reportThreadPool() {
        return new EventThreadPool();
    }
    @Bean("roomReservationThreadPool")
    public ThreadPoolExecutor roomReservationThreadPool() {
        return new EventThreadPool();
    }
}

image.gif

4、在自己的方法中使用

package com.javabase.Thread;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
/**
 * 构建执行定时任务
 * TODO
 */
@Component
@EnableScheduling
public class ScheduledTask3 {
    private Logger logger = LoggerFactory.getLogger(ScheduledTask3.class);
 
    private int fixedDelayCount = 1;
    private int fixedRateCount = 1;
    private int initialDelayCount = 1;
    private int cronCount = 1;
 
  /*  @Scheduled(fixedDelay = 5000)        //fixedDelay = 5000表示当前方法执行完毕5000ms后,Spring scheduling会再次调用该方法
    public void testFixDelay() {
        logger.info("===fixedDelay: 第{}次执行方法", fixedDelayCount++);
    }
 
    @Scheduled(fixedRate = 5000)        //fixedRate = 5000表示当前方法开始执行5000ms后,Spring scheduling会再次调用该方法
    public void testFixedRate() {
        logger.info("===fixedRate: 第{}次执行方法", fixedRateCount++);
    }
 
    @Scheduled(initialDelay = 1000, fixedRate = 5000)   //initialDelay = 1000表示延迟1000ms执行第一次任务
    public void testInitialDelay() {
        logger.info("===initialDelay: 第{}次执行方法", initialDelayCount++);
    }*/
 
    /*@Scheduled(cron = "0 0/1 * * * ?")  //cron接受cron表达式,根据cron表达式确定定时规则
    public void testconfigureTasks() {
        logger.info("===initialDelay: 第{}次执行方法", cronCount++);
    }*/
    @Async("RewardThreadPool")
    @Scheduled(cron = "0/1 * * * * ?")
    public void testtaskExecutor() {
        logger.info("ScheduledTask3定时任务开始 :{} " + "\r\n线程 : {}", LocalDateTime.now().toLocalTime(), Thread.currentThread().getName());
        logger.info("===initialDelay: 第{}次执行方法", cronCount++);
    }
}

image.gif


目录
相关文章
|
6天前
|
安全 Java
并发编程之常见线程安全类以及一些示例的详细解析
并发编程之常见线程安全类以及一些示例的详细解析
15 0
|
6天前
|
安全 Java API
Java多线程编程:使用Atomic类实现原子操作
【4月更文挑战第6天】Java的`java.util.concurrent.atomic`包提供了一系列原子类,如`AtomicInteger`和`AtomicLong`,利用CPU原子指令保证无锁情况下变量更新的原子性,从而实现线程安全。这些类在高并发场景下能避免线程阻塞,提高性能。`AtomicInteger`和`AtomicLong`支持原子地增加、减少和设置值,而`AtomicReference`则适用于原子更新引用对象。尽管原子类具有非阻塞、线程安全和易用等优点,但它们仅保证单个变量的原子性,复杂操作可能仍需传统同步机制。了解其工作原理和局限性,有助于提升并发应用性能。
|
6天前
|
安全 Java 开发者
【JAVA】哪些集合类是线程安全的
【JAVA】哪些集合类是线程安全的
|
2天前
|
安全 Java 容器
Java一分钟之-并发编程:线程安全的集合类
【5月更文挑战第19天】Java提供线程安全集合类以解决并发环境中的数据一致性问题。例如,Vector是线程安全但效率低;可以使用Collections.synchronizedXxx将ArrayList或HashMap同步;ConcurrentHashMap是高效线程安全的映射;CopyOnWriteArrayList和CopyOnWriteArraySet适合读多写少场景;LinkedBlockingQueue是生产者-消费者模型中的线程安全队列。注意,过度同步可能影响性能,应尽量减少共享状态并利用并发工具类。
17 2
|
6天前
|
监控 Java Spring
Spring Boot中一般如何使用线程池?
在Spring Boot应用程序中,合理地使用线程池可以有效地提高系统的性能和并发处理能力。本文将深入探讨Spring Boot中如何一般性地使用线程池,包括线程池的配置、使用方式以及一些最佳实践。
28 0
|
6天前
|
安全 Java 调度
Java一分钟:多线程编程初步:Thread类与Runnable接口
【5月更文挑战第11天】本文介绍了Java中创建线程的两种方式:继承Thread类和实现Runnable接口,并讨论了多线程编程中的常见问题,如资源浪费、线程安全、死锁和优先级问题,提出了解决策略。示例展示了线程通信的生产者-消费者模型,强调理解和掌握线程操作对编写高效并发程序的重要性。
47 3
|
6天前
|
Java
【Java多线程】面试常考 —— JUC(java.util.concurrent) 的常见类
【Java多线程】面试常考 —— JUC(java.util.concurrent) 的常见类
24 0
|
6天前
|
Java API 调度
【Java多线程】Thread类的基本用法
【Java多线程】Thread类的基本用法
12 0
|
6天前
|
算法 安全 调度
【C++入门到精通】 线程库 | thread类 C++11 [ C++入门 ]
【C++入门到精通】 线程库 | thread类 C++11 [ C++入门 ]
17 1
|
6天前
|
存储 缓存 前端开发
Java串口通信技术探究3:RXTX库线程 优化系统性能的SerialPortEventListener类
Java串口通信技术探究3:RXTX库线程 优化系统性能的SerialPortEventListener类
58 3