本文主要分享线程池的动态拓容、判断执行任务执行完毕、线程任务提交速度限制三个线程池使用技巧。
ThreadPoolExecutor taskExecutor = new ThreadPoolExecutor(8, 64, 5, TimeUnit.SECONDS, new LinkedBlockingQueue<>(256), new ThreadFactoryBuilder().setNameFormat("customer-worker-%d").build(), (task, executor) -> { try { executor.getQueue().put(task); } catch (InterruptedException e) { logger.error("customer-worker 线程阻断异常:" + e.getMessage(), e); } }); 复制代码
动态拓展容量
触发方式,我们可以通过 apollo 配置或者通过延迟任务定期扫描自动拓展
// 配置信息 @Value("${corePoolSize:2}") private Integer corePoolSize; @Value("${corePoolSize:8}") private Integer maximumPoolSize; // 修改线程池核心参数,提高并发度 taskExecutor.setCorePoolSize(corePoolSize); taskExecutor.setMaximumPoolSize(maximumPoolSize); 复制代码
可以通过这种方式对生产环境线程池参数进行动态优化。
线程池的使用可以提高我们并发程序线程复用,以及提供对线程的管理能力。提高线程的利用率,提升性能。但是对于一些场景我们需要知道当前线程池中提交的任务是否执行完毕,我们可以通过以下4种方式判断。
threadPool.isTerminated() 常用来判断线程池是否结束,结束了为TRUE.
使用 threadPool.isTerminated() 方法,必须在shutdown()方法关闭线程池之后才能使用,否则isTerminated()永不为TRUE,线程将一直阻塞在该判断的地方,导致程序最终崩溃。
/** * 线程池任务执行完成判断 */ public class ThreadPoolCompleted { public static void main(String[] args) { // 1.创建线程池 ThreadPoolExecutor threadPool = new ThreadPoolExecutor(10, 20, 0, TimeUnit.SECONDS, new LinkedBlockingDeque<>(1024)); // 2.添加任务 addTask(threadPool); // 3.判断线程池是否执行完 isCompleted(threadPool); // 【核心调用方法】 // 4.线程池执行完 System.out.println(); System.out.println("线程池任务执行完成!"); } /** * 方法1:isTer