1 合理设计参数
java线程池合理设置最大线程数和核心线程数_李振伟的博客-CSDN博客_java线程池核心线程数和最大线程数
corePoolSize:核心线程 ,一般线程数设置为 CPU核心数 或者 2* CPU核心数
MaxPoolSize:最大线程数, 2* CPU核心数 或者 4*CPU核心数
2 队列的选择
3 代码实战
@Configuration
public class ThreadConfig {
@Bean
public ThreadPoolTaskExecutor submitPassThreadPool() {
ThreadPoolTask executor = new ThreadPoolTask();
//获取CPU核心数
int corePoolSize = Runtime.getRuntime().availableProcessors();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(corePoolSize * 2);
// 设置线程活跃时间,单位秒 默认60秒
// executor.setKeepAliveSeconds(60);
// 设置核心线程超时回收
// executor.setAllowCoreThreadTimeOut(true);
//实际使用中出现任务过多时会导致内存溢出
executor.setQueueCapacity(80);
//有四个不同策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setThreadNamePrefix("thread-");
executor.initialize();
return executor;
}
}
4监控线程池报警
定时器 5秒执行一次查询
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.concurrent.ThreadPoolExecutor;
@Slf4j
@Component
public class ThreadConfig2 {
@Resource(name = "submitPassThreadPool")
ThreadPoolTaskExecutor submitPassThreadPool;
/**
* 监控每秒执行一次
*/
@Scheduled(cron = "* * * * * ?")
public void monitor() {
//获取正在执行任务的线程数据
ThreadPoolExecutor threadPoolExecutor = submitPassThreadPool.getThreadPoolExecutor();
log.info("{} taskCount [{}], completedTaskCount [{}],largestPoolSize[{}], activeCount [{}], queueSize [{}]",
//线程前缀名
submitPassThreadPool.getThreadNamePrefix(),
//返回线程池收到的任务总数。
threadPoolExecutor.getTaskCount(),
//线程池完成任务的数量。
threadPoolExecutor.getCompletedTaskCount(),
//返回线程池曾经达到的线程的最大数。
threadPoolExecutor.getLargestPoolSize(),
//返回 正在执行任务的线程数。
threadPoolExecutor.getActiveCount(),
//返回队列中的元素数。 (有多少任务堵塞在队列)
threadPoolExecutor.getQueue().size());
/* ThreadPoolExecutor提供了一组方法用于监控线程池。
int getActiveCount() 获得线程池中当前活动线程的数量。
long getCompletedTaskCount() 返回线程池完成任务的数量。
int getCorePoolSize() 线程池中核心线程的数量。
int getLargestPoolSize() 返回线程池曾经达到的线程的最大数。
int getMaximumPoolSize() 返回线程池的最大容量。
int getPoolSize() 当前线程池的大小。
BlockingQueue getQueue() 返回阻塞队列。
long getTaskCount() 返回线程池收到的任务总数。*/
}
/**
* 调用线程
*/
@Scheduled(cron = "0/5 * * * * ? ")
public void monito2r() {
int count=0;
count++;
int finalCount = count;
for (int i = 0; i < 20; i++) {
submitPassThreadPool.execute(()->{
System.err.println(Thread.currentThread().getName()+" 执行任务的当前次数:"+ finalCount);
});
}
}
}