Java和Spring中线程池创建方法

一、线程池定义

1.JDK中线程池类图

Executor:父接口,所有线程池都实现了这个接口,里面有一个excute()方法用于执行线程

ExecutorService:线程池接口,继承自Executor接口,供了生命周期管理的方法,返回 Future 对象,可以返回执行完的结果

ThreadPoolExecutor:线程池的具体实现类,一般使用ThreadPoolExecutor创建线程池

 

2.创建线程池的工具类

Executors:线程池的工具类,用于创建线程池,返回ExecutorService类型的线程池

1)public static ExecutorService newFiexedThreadPool(int Threads) :创建固定数目线程的线程池

2)public static ExecutorService newCachedThreadPool():创建一个可缓存的线程池,调用execute 将重用以前构造的线程(如果线程可用)。如果没有可用的线程,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程

3)public static ExecutorService newSingleThreadExecutor():创建一个单线程化的Executor

4)public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize):调度型线程池

3.区别

1)Executor 接口定义了 execute()方法用来接收一个Runnable接口的对象,不接受返回的对象,而 ExecutorService 接口中的 submit()方法可以通过Future 对象接受RunnableCallable接口的对象

2)ExecutorService 还提供用来控制线程池的方法。比如:调用 shutDown() 方法终止线程池

3)Executors 类提供工厂方法用来创建不同类型的线程池

4.线程池参数

corePoolSize:核心线程数

maximumPoolSize, //最大线程数

keepAliveTime:当线程数超过核心线程数,线程的最大存活时间

unit:keepAliveTime的时间单位

workQueue:阻塞队列

threadFactory: 创建线程的工厂

handler:拒绝策略

5.线程池执行顺序

1)当线程数小于 corePoolSize时,创建线程执行任务。

2)当线程数大于等于 corePoolSize并且 workQueue 没有满时,放入workQueue

3)线程数大于等于 corePoolSize并且当 workQueue 满时,新任务新建线程运行,线程总数要小于 maximumPoolSize

4)当线程总数等于 maximumPoolSize 并且 workQueue 满了的时候执行 handlerrejectedExecution。也就是拒绝策略

6.拒绝访问策略

ThreadPoolExecutor默认有四个拒绝策略:

1、ThreadPoolExecutor.AbortPolicy() 直接抛出异常RejectedExecutionException

2、ThreadPoolExecutor.CallerRunsPolicy() 直接调用run方法并且阻塞执行

3、ThreadPoolExecutor.DiscardPolicy() 直接丢弃后来的任务

4、ThreadPoolExecutor.DiscardOldestPolicy() 丢弃在队列中队首的任务

当然可以自己继承RejectedExecutionHandler来写拒绝策略.

 

二、线程池使用方法

1.Java JDK创建线程池的方法-ThreadPoolExecutor

1)使用ThreadPoolExecutor创建线程池

API如下所示:

public ThreadPoolExecutor(int corePoolSize,  //核心线程数
                          int maximumPoolSize, //最大线程数
                          long keepAliveTime,   //当线程数超过核心线程数,线程的最大存活时间
                          TimeUnit unit,        //keepAliveTime的时间单位
                          BlockingQueue<Runnable> workQueue) //阻塞队列容量
                          { 
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
         Executors.defaultThreadFactory(), defaultHandler);
}

所在包:java.util.concurrent.*

2)代码实现:

3)结果展示:

 

2.Spring创建线程池方式-ThreadPoolTaskExecutor

所在包:package org.springframework.core.task;

创建线程池并注入spring容器,开启@EnableAsync注解方便后续使用它@Async异步化调用


 

@Configuration
@EnableAsync
public class BeanConfig {

    @Bean
    public ThreadPoolTaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 设置核心线程数
        executor.setCorePoolSize(5);
        // 设置最大线程数
        executor.setMaxPoolSize(10);
        // 设置队列容量
        executor.setQueueCapacity(20);
        // 设置线程活跃时间(秒)
        executor.setKeepAliveSeconds(60);
        // 设置默认线程名称
        executor.setThreadNamePrefix("hello-");
        // 设置拒绝策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 等待所有任务结束后再关闭线程池
        executor.setWaitForTasksToCompleteOnShutdown(true);
        return executor;
    }
}

3.异步调用线程池线程方法-ThreadPoolTaskExecutor

1)代码处使用

需要使用@Autowired装配获取注入的线程池对象

    @Autowired
    private ThreadPoolTaskExecutor executor;
​
    /**
     * 根据活动id获取指定活动,异步添加缓存操作
     */
    @RequestMapping("/test9")
    public String testTaskExecutor() throws Throwable {
        log.info("进入方法:");
        //异步调用
        executor.execute(() -> {
            try {
                log.info("进入异步方法:");
                Thread.sleep(2000);
                jedisClusterClient.getJedisCluster().set("test9:async", "test");
​
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("异步执行添加缓存:" + jedisClusterClient.getJedisCluster().get("test9:async"));
        });
        log.info("方法执行完毕");
        return "test";
    }

执行结果:

可以看到异步执行是在方法执行完毕后才执行的,不是同步的,异步化成功

2)使用@Async注解异步调用

注意:@Async修饰的方法的实例必须注入spring容器中方能使用,代码如下:

异步方法使用@Async调用:

执行结果:

可以看到结果也是异步化调用

<think>好的,用户问的是如何在Spring框架中创建线程池的示例配置。我需要结合之前提供的引用内容来回答。首先,用户可能已经看过一些关于线程池配置的属性,比如coreSize、maxSize等,这些在ThreadPoolConfigProperties类中提到了。然后引用23提到了使用ThreadPoolTaskExecutor来配置线程池,以及启用@EnableAsync创建异步任务的方法。 我应该分步骤来回答,这样结构更清晰。首先需要说明在Spring创建线程池的两种常见方式:使用ThreadPoolTaskExecutor或者通过配置文件。然后给出具体的配置示例,包括Java配置类属性文件的设置。接着要提到启用异步支持需要@EnableAsync注解,最后展示如何在业务代码中使用异步方法。 还要注意用户可能想了解各个参数的意义,比如核心线程数、最大线程数等,所以需要解释这些参数的作用。同时,示例代码部分要正确,确保语法正确,并且符合Spring的实践。另外,用户可能需要知道如何测试使用这个线程池,所以加上调用示例也是有帮助的。 最后,生成的相关问题需要围绕线程池配置的细节、参数确定方法以及常见问题,比如阻塞队列的选择或者异常处理。这样用户如果有进一步的问题,也能找到方向。</think>在Spring框架中创建线程池主要通过`ThreadPoolTaskExecutor`实现,以下是详细配置步骤及示例: ### 一、基础配置步骤 1. **创建线程池配置类** ```java @Configuration @EnableAsync // 开启异步支持 public class ThreadPoolConfig { @Bean("taskExecutor") public ThreadPoolTaskExecutor taskExecutor(ThreadPoolConfigProperties properties) { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(properties.getCoreSize()); executor.setMaxPoolSize(properties.getMaxSize()); executor.setQueueCapacity(100); executor.setKeepAliveSeconds(properties.getKeepAliveTime()); executor.setThreadNamePrefix("spring-thread-"); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); executor.initialize(); return executor; } } ``` 2. **配置文件(application.yml)** ```yaml bookstore: thread: core-size: 5 max-size: 10 keep-alive-time: 60 ``` ### 二、参数说明 - `corePoolSize`:核心线程数,默认保持存活的线程数($N_{core}$) - `maxPoolSize`:最大线程数,当队列满时创建新线程的上限($N_{max}$) - `queueCapacity`:任务队列容量,队列满后才会创建新线程 - `keepAliveSeconds`:非核心线程空闲存活时间(秒) - `RejectedExecutionHandler`:当队列线程池都满时的拒绝策略[^2] ### 三、异步调用示例 ```java @Service public class OrderService { @Async("taskExecutor") // 指定线程池名称 public CompletableFuture<Order> processOrderAsync(Order order) { // 模拟耗时操作 return CompletableFuture.completedFuture(order); } } ``` ### 四、关键注意事项 1. **启动类必须添加`@EnableAsync`** ```java @SpringBootApplication @EnableAsync // 关键注解 public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` 2. **线程池调用逻辑顺序** $$ \text{核心线程} \rightarrow \text{任务队列} \rightarrow \text{非核心线程} \rightarrow \text{拒绝策略} $$ 当核心线程全忙时,新任务进入队列;队列满后扩容至最大线程数;仍超负荷时触发拒绝策略[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值