各类线程池的使用(工具类)

一:只有一个线程的线程池

二:固定数量的线程池

三:缓存线程池

四:延时线程池

此处列一个具体示例:使用延时线程池做定时任务,每半小时执行一次(时间可自定义),执行具体的业务逻辑

@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) {
      }
    }
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值