springboot与线程
springboot有一个自带的线程池类,就是ThreadPoolTaskExecutor
1 配置
1.1 配置前置解释
@EnableAsync:开启异步任务
setCorePoolSize:核心线程数
setMaxPoolSize:最大线程数
setQueueCapacity:队列大小
setThreadNamePrefix:线程名称前缀
setKeepAliveSeconds:线程活跃时间
setWaitForTasksToCompleteOnShutdown:所有任务结束再关闭线程池
setRejectedExecutionHandler:拒绝策略
initialize:初始化
1.2 config 配置
直接配置
package com.hc.store.thread;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
/**
* @author chajintao
* @date 2022/4/26 16:36
*/
@Configuration
@EnableAsync //开启异步任务
public class ThreadConfig {
@Bean
public ThreadPoolTaskExecutor executor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//配置核心线程数
executor.setCorePoolSize(15);
//配置最大线程数
executor.setMaxPoolSize(30);
//配置队列大小
executor.setQueueCapacity(1000);
//线程名称前缀
executor.setThreadNamePrefix("executor-");
//线程活跃时间(秒)
executor.setKeepAliveSeconds(60);
//等待所有任务结束后再关闭线程池
executor.setWaitForTasksToCompleteOnShutdown(true);
//设置拒绝策略
//executor.setRejectedExecutionHandler(new java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy());
//执行初始化
executor.initialize();
return executor;
}
}
2 测试
对比普通的插入操作和多线程操作的效果
2.1 实体类Threads
创建实体类Threads
package com.hc.store.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
* 线程测试参数
* @author chajintao
* @date 2022/4/26 16:46
*/
@Data
@TableName("threads")
public class Threads {
@TableId(type = IdType.AUTO)
private String id;
private String threadName;
private String number;
}
2.2 controller
package com.hc.store.thread;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.hc.store.model.Threads;
import com.hc.store.service.ThreadService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* Thread测试
* @author chajintao
* @date 2022/4/26 16:56
*/
@Slf4j
@RestController
@RequestMapping("/ex")
public class ThreadController {
@Autowired
private ThreadService threadService;
@Autowired
private ThreadPoolTaskExecutor executor;
@RequestMapping("/save")
public long save() {
log.info("开始");
Date date1 = new Date();
List<Threads> threads = new ArrayList<>();
for (int i = 0; i < 10000; i++) {
Threads thread = new Threads();
thread.setThreadName("thread" + RandomUtil.randomNumbers(6));
thread.setNumber("num"+i);
log.info("thread:{}" + thread);
threads.add(thread);
}
executor.execute(() -> threadService.addBatch(threads));
Date date2 = new Date();
return DateUtil.between(date1,date2, DateUnit.MS);//98
}
@RequestMapping("/save1")
private long save1() {
Date date1 = new Date();
List<Threads> threads = new ArrayList<>();
for (int i = 0; i < 10000; i++) {
Threads thread = new Threads();
thread.setThreadName("thread" + RandomUtil.randomNumbers(6));
thread.setNumber("num"+i);
log.info("thread:{}" + thread);
threads.add(thread);
}
threadService.addBatch(threads);
Date date2 = new Date();
return DateUtil.between(date1,date2, DateUnit.MS);//25635
}
}
2.3 service
业务接口
package com.hc.store.service;
import com.hc.store.model.Threads;
import java.util.List;
/**
* 业务接口
* @author chajintao
* @date 2022/4/26 16:45
*/
public interface ThreadService {
/**
* 批量新增
*/
boolean addBatch(List<Threads> threadsList);
}
2.4 impl
package com.hc.store.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hc.store.model.Threads;
import com.hc.store.service.ThreadService;
import com.hc.store.mapper.ThreadMapper;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* threads业务接口实现
* @author chajintao
* @date 2022/4/26 16:48
*/
@Service
public class ThreadServiceImpl extends ServiceImpl<ThreadMapper,Threads> implements ThreadService {
@Override
public boolean addBatch(List<Threads> threadsList) {
return saveBatch(threadsList);
}
}
2.5 mapper
package com.hc.store.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.hc.store.model.Threads;
/**
* @author chajintao
* @date 2022/4/26 16:50
*/
public interface ThreadMapper extends BaseMapper<Threads> {
}
2.6 比较
经过测试,线程池所需要的时间是98毫秒,普通插入需要25635毫秒
3 总结
使用线程池确实比普通查询快了很多,而且springboot自带的线程池类,比较容易配置,在网上一搜一大堆,容易实现。