线程池是Java实现并发的第一步,以下在SpringBoot中配置线程池的步骤,简单易学,小白也可以配置。
编写一个类,实例化线程池的数学参数:包括核心线程数、最大线程数、允许挂载时间、阻塞队列数:
//线程池的几个整数的参数,用到配置文件application.yml和dev配合一起配置;
// 在application.yml中别忘了active: dev 激活application-dev.yml配置文件
@Component
@ConfigurationProperties(prefix = "thread.pool")
@Data
public class ThreadPoolProperties {
private Integer corePoolSize;//核心线程池数
private Integer maximumPoolSize;//最大线程数
private Integer keepAliveTime;//秒
private Integer queue;//允许排队的队列数,程序阻塞数
}
appliaction.yaml和dev参数:
#线程池属性的配置
thread:
pool:
corePoolSize: ${pool.corePoolSize}
maximumPoolSize: ${pool.maximumPoolSize}
keepAliveTime: ${pool.keepAliveTime}
queue: ${pool.queue}
dev:
#线程池具体参数配置
pool:
corePoolSize: 2
maximumPoolSize: 3
keepAliveTime: 5
queue: 3
别忘了在application.yml激活dev文件:
spring:
profiles:
active: dev
配置线程池Bean:
//配置类
@Configuration
public class Configurations {
//注入刚刚配置类实例化的线程数学方面的参数类:
@Autowired
private ThreadPoolProperties poolProperties;
@Bean()
public ThreadPoolExecutor threadPoolExecutor() {
ThreadPoolExecutor executor = new ThreadPoolExecutor(poolProperties.getCorePoolSize(),//核心线程池数
poolProperties.getMaximumPoolSize(), //最大线程数
poolProperties.getKeepAliveTime(), //线程挂载时长
TimeUnit.SECONDS,//时长单位 (这里用秒)
new ArrayBlockingQueue<>(poolProperties.getQueue()));//允许排队的队列数,程序阻塞数
executor.allowCoreThreadTimeOut(true);//挂在时间到了仍然没有程序使用线程就允许线程挂掉。
return executor;
}
}
具体使用:测试单元:
注意:测试单元的@Test注解对多线程执行不是很友好;因为在@Test注解下的主程序方法只认主程序的主线程;其他的线程并不照顾到;主线程运行完即挂掉停止程序;为了简单演示;这里用到了线程阻塞;Thread.sleep(3000);即阻塞主线程3秒钟;等待线程池的线程运行完才关闭主线程;
@SpringBootTest
public class Test {
@Autowired(required = false)
private InsertBatchMapper insertBatchMapper;
//注入线程池Bean;
@Autowired
private ThreadPoolExecutor threadPoolExecutor;
@org.junit.jupiter.api.Test
public void testUmbrella()throws Exception{
String s="北京";
threadPoolExecutor.execute(()->{ //线程执行的具体操作:: Lambda写法
List<UserAuto>list=new ArrayList<>();
for (int i=0;i<30;i++) {
UserAuto userAuto = new UserAuto(s,"女",28,38);
list.add(userAuto);
}
insertBatchMapper.insertBatch(list);
});threadPoolExecutor.execute(()->{ 线程执行的具体操作:: Lambda写法
List<UserAuto>list=new ArrayList<>();
for (int i=0;i<30;i++) {
UserAuto userAuto = new UserAuto(s,"女",28,38);
list.add(userAuto);
}
insertBatchMapper.insertBatch(list);
});threadPoolExecutor.execute(()->{// //线程执行的具体操作:: Lambda写法
List<UserAuto>list=new ArrayList<>();
for (int i=0;i<30;i++) {
UserAuto userAuto = new UserAuto(s,"女",28,38);
list.add(userAuto);
}
insertBatchMapper.insertBatch(list);
System.out.println("ThreadName:"+Thread.currentThread());
});threadPoolExecutor.execute(()->{/// //线程执行的具体操作:: Lambda写法
List<UserAuto>list=new ArrayList<>();
for (int i=0;i<30;i++) {
UserAuto userAuto = new UserAuto(s,"女",28,38);
list.add(userAuto);
}
insertBatchMapper.insertBatch(list);
System.out.println("ThreadName:"+Thread.currentThread());
}); ///一共四个任务,
Thread.sleep(3000);///注意:
// @Test注解中;主线程运行完即关闭整个程序;并不会等待主程序中其他的线程运行完毕才关闭;
//而是直接关闭了整个程序;有可能会导致主程序中其他的线程线程还未执行完毕就挂掉整个程序;
///为此:在主程序中阻塞等待三秒,确保全部线程全部执行完毕;具体解决方案是编写CountDownLatch进行控制
}
}
测试结果:
测试结果跟设置好的线程数大致相符:
#线程池具体参数配置
pool:
corePoolSize: 2
maximumPoolSize: 3
keepAliveTime: 5
queue: 3