一:只有一个线程的线程池
二:固定数量的线程池
三:缓存线程池
四:延时线程池
此处列一个具体示例:使用延时线程池做定时任务,每半小时执行一次(时间可自定义),执行具体的业务逻辑
@Component
public class HWAdvertRingJob extends SelectBaseServiceImpl {
private static ScheduledExecutorService pool = Executors.newSingleThreadScheduledExecutor();
@PostConstruct
public void initJob(){
String localIp = IpUtil.getLocalIp();
if(localIp != "192.168.105.31"){
Runnable task1 = () -> {
try {
executeStartOrEndTime();
}catch (Exception e){
error(e,"执行定时任务:查询生失效时间异常");
}
};
/** 系统启动的时候执行一次,之后以系统启动时间为基准,每30分钟执行一次 */
pool.scheduleWithFixedDelay(task1, 0, 30, TimeUnit.MINUTES);
}
}
// 执行具体的业务逻辑
private void executeStartOrEndTime() throws Exception {
log("执行定时任务:查询生失效时间,用于同步大区");
.................
}
}
项目中使用线程池的示例:
// 监听线程池(独立)
private ThreadPoolExecutor listeners = ThreadPoolUtils.createPool(2, "监听线程");
// 数据库操作线程池(共用)
public static ThreadPoolExecutor dbFetchPool = null;
// 话单上报线程池(共用)
public static ThreadPoolExecutor reportPool = null;
private void initBizProps(){
// 初始化数据库线程池
// 特别注意: 数据库线程名称不能使用中文, 否则连接DB失败!
dbFetchPool = refreshThreadPool(dbFetchPool, this.fetchPoolCore, "Fetcher");
// 初始化话单上报线程池
reportPool = refreshThreadPool(reportPool, this.reportPoolCore, reportQueueSize, "话单上报");
}
protected void generateDbTasks(TimeRange timeRange) {
// 遍历所有分区, 每个分区产生一个任务给线程池处理
for (int partition = 0; partition < PARTITIONS_COUNT; partition++) {
PartitionTimeRange pt = new PartitionTimeRange(timeRange, formatPartition(partition));
dbFetchPool.execute(() -> this.prepareReportBill(pt));
}
}
private void enReportPool(E reportRequest) {
reportPool.execute(() -> {
reportBill(reportRequest);
});
}
/**
* 阻塞监听任务完成
*/
private void listeningTasksCompleted() {
listeners.execute(() -> {
LocalDateTime exeStart = LocalDateTime.now();
try {
log.info("等待数据库线程池关闭...");
awaitPoolClosed(dbFetchPool);
log.info("等待话单缓冲全部提交...");
awaitWorkQueueEmpty(reportQueue);
log.info("等待话单线程池关闭...");
awaitPoolClosed(reportPool);
log.info("等待释放内存空间...");
RelationCacheUtils.clearCaches();
log.info("等待发送短信...");
sendSmsMessage(exeStart);
} catch (Exception ex) {
log.error("监听任务失败:{}", ex.getMessage(), ex);
}
});
}
private void throwExIfRunningTask() {
boolean noRunningTask = (reportPool == null || reportPool.isTerminated());
Assert.state(noRunningTask, "请等待当前任务结束!");
}
自定义线程池工具类:
import static java.util.concurrent.TimeUnit.SECONDS;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import lombok.extern.slf4j.Slf4j;
/**
* 线程池工具类
*/
@Slf4j
public class ThreadPoolUtils {
/**
* 刷新线程池
* 若线程池为空或已经关闭, 则创建新线程池代替
* @param executor
* @param coreThreads
* @param threadName
* @return
*/
public static ThreadPoolExecutor refreshThreadPool(@Nullable ThreadPoolExecutor executor, int coreThreads, String threadName) {
if (executor == null || executor.isTerminated()) {
executor = createPool(coreThreads, Integer.MAX_VALUE, threadName);
}
return executor;
}
public static ThreadPoolExecutor refreshThreadPool(@Nullable ThreadPoolExecutor executor, int coreThreads, int queueSize, String threadName) {
if (executor == null || executor.isTerminated()) {
executor = createPool(coreThreads, queueSize, threadName);
}
return executor;
}
/**
* 创建线程池
*
* @param coreThreads 核心线程数
* @param threadNamePrefix 线程名称前缀
*/
public static ThreadPoolExecutor createPool(int coreThreads, String threadNamePrefix) {
return createPool(coreThreads, Integer.MAX_VALUE, threadNamePrefix);
}
/**
* 创建线程池
*
* @param coreThreads 核心线程数
* @param queueSize 队列数
* @param threadNamePrefix 线程名称前缀
*/
public static ThreadPoolExecutor createPool(Integer coreThreads, Integer queueSize, String threadNamePrefix) {
ThreadPoolExecutor newPool = new ThreadPoolExecutor(
coreThreads, coreThreads, 60, TimeUnit.SECONDS,
new LinkedBlockingQueue<>(queueSize),
new ThreadFactoryBuilder().setNameFormat(threadNamePrefix + "-%d").setDaemon(false).build());
log.info("初始化[{}]线程池 with core threads {}", threadNamePrefix, newPool.getCorePoolSize());
return newPool;
}
/**
* 阻塞等待线程池关闭
* @param executorService
*/
public static void awaitPoolClosed(ExecutorService executorService) {
if (executorService != null && !executorService.isShutdown()) {
executorService.shutdown();
while (true){
if (executorService.isTerminated()) {
break;
}
try {
executorService.awaitTermination(60, SECONDS);
} catch (Exception e) { log.error("等待线程池关闭中断:{}", e.getMessage(), e); }
}
}
}
/**
* 阻塞等待队列完成
* @param workQueue
*/
public static void awaitWorkQueueEmpty(BlockingQueue workQueue) {
while (true) {
if (workQueue.isEmpty()) {
break;
}
try {
Thread.sleep(60000);
} catch (InterruptedException ignoreEx) {
}
}
}
}