JAVA 多线程-异步

73 阅读2分钟
# 核心池大小
thread.corePoolSize = 10
# 最大线程数
thread.maxPoolSize = 20
# 缓冲队列
thread.queueCapacity = 100
# 线程空闲时间
thread.threadNamePrefix = 60
# 线程策略可以为空
thread.rejectedExecutionHandler = CallerRunsPolicy

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: ks
 * @Date: 2023/01/29/13:13
 * @Description:
 */
@Data
@Configuration
@PropertySource(value = "classpath:application-file.properties")
@ConfigurationProperties(prefix = "thread")
public class ThreadConfig {

    @ApiModelProperty("核心池大小")
    private Integer corePoolSize;

    @ApiModelProperty("最大线程数")
    private Integer maxPoolSize;

    @ApiModelProperty("缓冲队列")
    private Integer queueCapacity;

    @ApiModelProperty("线程空闲时间")
    private String  threadNamePrefix;

    @ApiModelProperty("线程策略")
    private String  rejectedExecutionHandler;

}

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: ks
 * @Date: 2023/01/29/10:22
 * @Description: AsyncConfigurer
 */
@Slf4j
@Component
@EnableAsync
public class ScheduleConfig  {

    @Resource
    private ThreadConfig threadConfig;

    private static final String EXECUTOR_NAME01 = "asyncExecutor01";

    private static final String EXECUTOR_NAME02 = "asyncExecutor02";

    @Bean(name = EXECUTOR_NAME01)
    public Executor getAsyncExecutor01() {
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        // 核心线程数
        threadPoolTaskExecutor.setCorePoolSize(threadConfig.getCorePoolSize());
        // 最大线程数
        threadPoolTaskExecutor.setMaxPoolSize(threadConfig.getMaxPoolSize());
        // 阻塞队列容量
        threadPoolTaskExecutor.setQueueCapacity(threadConfig.getQueueCapacity());
        // 空闲线程存活时间(单位:s)
        threadPoolTaskExecutor.setKeepAliveSeconds(300);
        // 待任务在关机时完成--表明等待所有线程执行完
        threadPoolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        // 线程名称前缀
        threadPoolTaskExecutor.setThreadNamePrefix(threadConfig.getThreadNamePrefix());
        // 设置拒绝策略
        threadPoolTaskExecutor.setRejectedExecutionHandler(getRejectedExecutionHandler(threadConfig.getRejectedExecutionHandler()));
        threadPoolTaskExecutor.initialize();
        return threadPoolTaskExecutor;
    }

    @Bean(name = EXECUTOR_NAME02)
    public Executor getAsyncExecutor02() {
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        // 核心线程数
        threadPoolTaskExecutor.setCorePoolSize(threadConfig.getCorePoolSize());
        // 最大线程数
        threadPoolTaskExecutor.setMaxPoolSize(threadConfig.getMaxPoolSize());
        // 阻塞队列容量
        threadPoolTaskExecutor.setQueueCapacity(threadConfig.getQueueCapacity());
        // 空闲线程存活时间(单位:s)
        threadPoolTaskExecutor.setKeepAliveSeconds(300);
        // 待任务在关机时完成--表明等待所有线程执行完
        threadPoolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        // 线程名称前缀
        threadPoolTaskExecutor.setThreadNamePrefix(threadConfig.getThreadNamePrefix());
        // 设置拒绝策略
        threadPoolTaskExecutor.setRejectedExecutionHandler(getRejectedExecutionHandler(threadConfig.getRejectedExecutionHandler()));
        threadPoolTaskExecutor.initialize();
        return threadPoolTaskExecutor;
    }

    /**
     * 根据传入的参数获取拒绝策略
     * @param rejectedName 拒绝策略名,比如 CallerRunsPolicy
     * @return RejectedExecutionHandler 实例对象,没有匹配的策略时,默认取 CallerRunsPolicy 实例
     */
    public RejectedExecutionHandler getRejectedExecutionHandler(String rejectedName){
        Map<String, RejectedExecutionHandler> rejectedExecutionHandlerMap = new HashMap<>(16);
        // CallerRunsPolicy:不在新线程中执行任务,而是由调用者所在的线程来执行。"该策略既不会抛弃任务,也不会抛出异常,而是将任务回推到调用者。"
        rejectedExecutionHandlerMap.put("CallerRunsPolicy", new ThreadPoolExecutor.CallerRunsPolicy());
        // AbortPolicy:拒绝策略,直接拒绝抛出异常
        rejectedExecutionHandlerMap.put("AbortPolicy", new ThreadPoolExecutor.AbortPolicy());
        // DiscardPolicy: 直接丢弃
        rejectedExecutionHandlerMap.put("DiscardPolicy", new ThreadPoolExecutor.DiscardPolicy());
        // DiscardOldestPolicy: 丢弃队列中最老的任务
        rejectedExecutionHandlerMap.put("DiscardOldestPolicy", new ThreadPoolExecutor.DiscardOldestPolicy());
        return rejectedExecutionHandlerMap.getOrDefault(rejectedName, new ThreadPoolExecutor.CallerRunsPolicy());
    }
}
/**
 * Created with IntelliJ IDEA.
 *
 * @Author: ks
 * @Date: 2023/01/29/13:28
 * @Description:
 */
@Slf4j
@EnableAsync       // 开启异步
@EnableScheduling  // 开启定时任务
@Component
public class DataTask {

    @Async("asyncExecutor01")
    @Scheduled(cron = "0/10 * * * * *")
    public void a(){
        ....
    }
}