目录

 

前言

说明

代码实现

配置类

当需要执行异步调用时使用@Async注解

当需要执行有返回的任务时,返回值定义为Future


前言

线程池是为突然大量爆发的线程设计的,通过有限的几个固定线程为大量的操作服务,减少了创建和销毁线程所需的时间,从而提高效率。如果一个线程的时间非常长,就没必要用线程池了(不是不能作长时间操作,而是不宜。),况且还不能控制线程池中线程的开始、挂起、和中止。

说明

  • 1.配置解释

当一个任务通过execute(Runnable)方法欲添加到线程池时:

1.1、 如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。

1.2 如果此时线程池中的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。

1.3、如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。

1.4、 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。

也就是:处理任务的优先级为:核心线程corePoolSize、任务队列workQueue、最大线程 maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。

1.5、 当线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。

allowCoreThreadTimeout:允许核心线程超时
rejectedExecutionHandler:任务拒绝处理器

两种情况会拒绝处理任务:
当线程数已经达到maxPoolSize,切队列已满,会拒绝新任务
当线程池被调用shutdown()后,会等待线程池里的任务执行完毕,再shutdown。如果在调用shutdown()和线程池真正shutdown之间提交任务,会拒绝新任务
线程池会调用rejectedExecutionHandler来处理这个任务。如果没有设置默认是AbortPolicy,会抛出异常
ThreadPoolExecutor类有几个内部实现类来处理这类情况:
AbortPolicy 丢弃任务,抛运行时异常
CallerRunsPolicy 执行任务
DiscardPolicy 忽视,什么都不会发生
DiscardOldestPolicy 从队列中踢出最先进入队列(最后一个执行)的任务
实现RejectedExecutionHandler接口,可自定义处理器

代码实现

配置类

package *********;

import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.lang.reflect.Method;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @author 
 * @Title: AsyncConfig
 * @Description:
 * @Copyright: 
 * @Company: 
 * @Date 2020-03-19-9:31
 */
@Configuration
public class AsyncConfig implements AsyncConfigurer {

    private int corePoolSize = 5;//核心线程数
    private int maxPoolSize = 20;//最大线程数
    private int keepAliveSeconds = 60 * 10;//线程空闲时间
    private String threadNamePrefix = "my-Thread";//线程对象的名字前缀
    private int queueCapacity = 5;

    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        //设置核心线程数
        taskExecutor.setCorePoolSize(corePoolSize);
        //设置最大线程数
        taskExecutor.setMaxPoolSize(maxPoolSize);
        //设置线程空闲时间
        taskExecutor.setKeepAliveSeconds(keepAliveSeconds);
        //设置线程对象的名字前缀
        taskExecutor.setThreadNamePrefix(threadNamePrefix);
        //设置缓存队列的容量
        taskExecutor.setQueueCapacity(queueCapacity);
        //设置拒绝处理的策略(当线程池无法处理新的任务时,该执行什么策略)
        //new ThreadPoolExecutor.CallerRunsPolicy() 该策略为选择调用者线程进行处理
        //new ThreadPoolExecutor.AbortPolicy() 该策略为丢弃任务并抛出RejectedExecutionException异常(不设置时默认此策略)
        //new ThreadPoolExecutor.DiscardPolicy() 该策略为丢弃任务,但是不抛异常
        //new ThreadPoolExecutor.DiscardOldestPolicy() 该策略为丢弃队列最前面的任务,然后重新尝试执行任务
        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //初始化线程池
        taskExecutor.initialize();
        return taskExecutor;
    }

    //异常任务执行过程中的错误处理
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new AsyncUncaughtExceptionHandler() {
            @Override
            public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {
                //自定义处理

            }
        };
    }
}

@Configuration
class AsyncConfig1 {
    private int corePoolSize = 5;//核心线程数
    private int maxPoolSize = 20;//最大线程数
    private int keepAliveSeconds = 60 * 10;//线程空闲时间
    private String threadNamePrefix = "my-Thread";//线程对象的名字前缀
    private int queueCapacity = 5;

    @Bean
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        //设置核心线程数
        taskExecutor.setCorePoolSize(corePoolSize);
        //设置最大线程数
        taskExecutor.setMaxPoolSize(maxPoolSize);
        //设置线程空闲时间
        taskExecutor.setKeepAliveSeconds(keepAliveSeconds);
        //设置线程对象的名字前缀
        //taskExecutor.setThreadNamePrefix(threadNamePrefix);
        //设置缓存队列的容量
        taskExecutor.setQueueCapacity(queueCapacity);
        //允许核心线程超时
        taskExecutor.setAllowCoreThreadTimeOut(true);
        //设置拒绝处理的策略(当线程池无法处理新的任务时,该执行什么策略)
        //new ThreadPoolExecutor.CallerRunsPolicy() 该策略为选择调用者线程进行处理
        //new ThreadPoolExecutor.AbortPolicy() 该策略为丢弃任务并抛出RejectedExecutionException异常(不设置时默认此策略)
        //new ThreadPoolExecutor.DiscardPolicy() 该策略为丢弃任务,但是不抛异常
        //new ThreadPoolExecutor.DiscardOldestPolicy() 该策略为丢弃队列最前面的任务,然后重新尝试执行任务
        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        taskExecutor.setThreadFactory(new ThreadFactory() {
            private final AtomicLong index = new AtomicLong(1);

            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r, "thread-" + index.getAndIncrement());
            }
        });
        //初始化线程池
        //taskExecutor.initialize();当标记为Bean时,不需要调用此方法初始化,spring会自动调用此方法进行初始化
        return taskExecutor;
    }

    //异常任务执行过程中的错误处理
    @Bean
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new AsyncUncaughtExceptionHandler() {
            @Override
            public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {
                //自定义处理

            }
        };
    }

}

当需要执行异步调用时使用@Async注解

@Async
    public void AsyncExecutor(Object... objects){
        //执行任务
    }

当需要执行有返回的任务时,返回值定义为Future<T>

@Async
    public Future<String> AsyncExecutor(Object... objects){
        //执行任务
        return new AsyncResult<String>(JSON.toJSONString(objects));
    }