1,先添加线程池的公共配置类
package com.sport.sportactivityserver.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@Configuration
public class ApplicationConfiguration {
/**
* 公共线程池
*/
@Bean
public ThreadPoolTaskExecutor commonThreadPoolTaskExecutor() {
ThreadPoolTaskExecutor pool = new org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor();
int processNum = Runtime.getRuntime().availableProcessors(); // 返回可用处理器的Java虚拟机的数量
int corePoolSize = (int) (processNum / (1 - 0.2));
int maxPoolSize = (int) (processNum / (1 - 0.5));
pool.setCorePoolSize(corePoolSize); // 核心池大小
pool.setMaxPoolSize(maxPoolSize); // 最大线程数
pool.setQueueCapacity(maxPoolSize * 1000); // 队列程度
pool.setThreadPriority(Thread.MAX_PRIORITY);
pool.setDaemon(false);
pool.setKeepAliveSeconds(300);// 线程空闲时间
return pool;
}
}
2,使用线程池
package com.sport.sportactivityserver.controller.lottery;
import com.google.common.collect.Lists;
import com.sport.sportactivityserver.vo.ResultData;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
/**
* @Description:
* @Author: zdj
* @Date: 2021/11/23
* @version: 1.0.0
*/
@RestController
@RequestMapping("/thread-use")
@Api(tags = "线程池应用")
public class LyUserController {
/**
* 注入线程池对象
*/
@Qualifier("commonThreadPoolTaskExecutor")
@Autowired
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
@ApiOperation(value = "多线程--跑任务", notes = "多线程--跑任务", httpMethod = "POST")
@RequestMapping(value = "/textMoreThred", method = RequestMethod.POST)
public ResultData<Object> textMoreThred(){
// 开始时间
Long startTime = System.currentTimeMillis();
List<Integer> result = Lists.newArrayList();
for (int i = 1; i <= 3000000; i++) {
result.add(i);
}
System.out.println("多线程处理前结果:"+result);
/**
* partition()方法 大家可以看一下
* 例如 3001条数据 他会自动帮你分成两个数组 第一个数组3000条 第二个数组1条
* 不需要我们再像以前一样 通过for循环处理截取
*/
// 注入线程池
ExecutorCompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(threadPoolTaskExecutor);
List<List<Integer>> lists = Lists.partition(result, 300000);
lists.forEach(item -> {
// 这里做的事情就是 根据lists大小确认要多少个线程 给每个线程【分配】任务
completionService.submit(new Callable() {
@Override
public Object call() throws Exception {
for (int i = 0,len = item.size(); i < len; i++) {
item.set(i, item.get(i) + 1);
}
return true;
}
});
});
// 这里是让多线程开始执行
lists.forEach(item -> {
try {
completionService.take().get();
} catch (InterruptedException | ExecutionException e) {
System.out.println(e);
}
});
System.out.println("多线程处理后结果:"+result);
// 放在要检测的代码段前,取结束后的时间戳
Long endTime = System.currentTimeMillis();
return ResultData.error("多线程花费时间:"+this.getExpendTime((endTime - startTime)));
}
@ApiOperation(value = "单个线程--跑任务", notes = "单个线程--跑任务", httpMethod = "POST")
@RequestMapping(value = "/textOneThred", method = RequestMethod.POST)
public ResultData<Object> textOneThred(){
// 开始时间
Long startTime = System.currentTimeMillis();
List<Integer> result = Lists.newArrayList();
for (int i = 1; i <= 3000000; i++) {
result.add(i);
}
System.out.println("单线程处理前结果:"+result);
for (int i = 0,len = result.size(); i < len; i++) {
result.set(i, result.get(i) + 1);
}
System.out.println("单线程处理后结果:"+result);
// 结束时间
Long endTime = System.currentTimeMillis();
return ResultData.error("单线程花费时间:" + this.getExpendTime((endTime - startTime)));
}
/**
* 需要转化的时间
* @param tempTime
* @return
*/
private String getExpendTime(Long tempTime){
return (((tempTime / 86400000) > 0) ? ((tempTime / 86400000) + "d") : "") +
((((tempTime / 86400000) > 0) || ((tempTime % 86400000 / 3600000) > 0)) ? ((tempTime % 86400000 / 3600000) + "h") : ("")) +
((((tempTime / 3600000) > 0) || ((tempTime % 3600000 / 60000) > 0)) ? ((tempTime % 3600000 / 60000) + "m") : ("")) +
((((tempTime / 60000) > 0) || ((tempTime % 60000 / 1000) > 0)) ? ((tempTime % 60000 / 1000) + "s") : ("")) +
((tempTime % 1000) + "ms");
}
}
3,结果对比