配置线程池
首先我们需要先编写 启用@EnableAsync 的线程池配置类
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
//启动异步
@EnableAsync
//这是一个配置类
@Configuration
class TaskPoolConfig {
//设置Bean的名称不设置的话没有办法在 任务中对应 配置信息
@Bean("taskExecutor")
public Executor taskExecutor() {
//根据ThreadPoolTaskExecutor 创建建线程池
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//为线程设置初始的线程数量 5条线程
executor.setCorePoolSize(5);
//为线程设置最大的线程数量 10条线程
executor.setMaxPoolSize(10);
//为任务队列设置最大 任务数量
executor.setQueueCapacity(200);
//设置 超出初始化线程的 存在时间为60秒
//也就是 如果现有线程数超过5 则会对超出的空闲线程 设置摧毁时间 也就是60秒
executor.setKeepAliveSeconds(60);
//设置 线程前缀
executor.setThreadNamePrefix("taskExecutor-");
//线程池的饱和策略 我这里设置的是 CallerRunsPolicy 也就是由用调用者所在的线程来执行任务 共有四种
//AbortPolicy:直接抛出异常,这是默认策略;
//CallerRunsPolicy:用调用者所在的线程来执行任务;
//DiscardOldestPolicy:丢弃阻塞队列中靠最前的任务,并执行当前任务;
//DiscardPolicy:直接丢弃任务;
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//设置在关闭线程池时是否等待任务完成
executor.setWaitForTasksToCompleteOnShutdown(true);
//设置等待终止的秒数
executor.setAwaitTerminationSeconds(60);
//返回设置完成的线程池
return executor;
}
}
使用线程池的类
在使用线程池的时候我们需在使用线程池的任务方法上面加上@Async注解
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
//启用log 在控制台输出信息
@Slf4j
//启用@Component 注解将该类注入到spring容器中
@Component
public class test {
//为Hello类方法设置异步调用的配置类
@Async("taskExecutor")
public void Hello(String hello) throws InterruptedException {
//开始执行任务
log.info("任务开始并延长执行时间");
//延迟执行
Thread.sleep(1000);
//执行输出
log.info(hello);
}
}
测试线程池
编写测试线程池的方法这利用的idea 的单元测试
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {
//自动装配 线程测试类
@Autowired
private test test;
@Test
public void test() throws Exception {
//循环跑30个任务
for (int i = 0;i<30;i++){
test.Hello("test"+i);
}
}
}
这里需要说一下Spring有自己的线程池 我的这个属于自定义的线程池
同时Spring提供了定时任务调度的注解非常强大 @Scheduled+Cron配置
同时这个定时任务不与线程池发生冲突
下面附上非常详细 线程池详解
如果有错误的话请指出-爱学习的伤 2019-5-19 00:44:48
作者:伤_dffe
链接:https://www.jianshu.com/p/9094ad9df36c
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。