最近项目中进行告警模块性能优化,不少地方使用了线程池技术,整理总结如下。
package com.coshaho.threadpool; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Executors; import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * 线程池学习 * @author coshaho */ public class MyThreadPool { /** * 第一章 线程池初始化 */ // 核心线程数量 private int corePoolSize; // 最大线程数量 private int maximumPoolSize; // 空闲线程存活时间 private long keepAliveTime; // 空闲线程存活时间单位 private TimeUnit unit; // 线程阻塞队列 private BlockingQueue<Runnable> workQueue; /** * 线程创建工厂,一般自定义,用于封装传入ThreadPool的Runnable任务 * 默认:Executors.defaultThreadFactory() * public interface ThreadFactory { * Thread newThread(Runnable r); * } */ private ThreadFactory threadFactory; // 线程拒绝机制 private RejectedExecutionHandler handler; public void initThreadPoolExecutor() { ThreadPoolExecutor executor = new ThreadPoolExecutor( corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler); // 设置线程池核心线程数 executor.setCorePoolSize(corePoolSize); // 设置线程池最大线程数 executor.setMaximumPoolSize(maximumPoolSize); // 初始化一个核心线程 executor.prestartCoreThread(); // 初始化所有核心线程 executor.prestartAllCoreThreads(); // 不会立即终止线程池,而是要等所有任务缓存队列中的任务都执行完后才终止,但再也不会接受新的任务 executor.shutdown(); // 立即终止线程池,尝试打断正在执行的任务,并且清空任务缓存队列,返回尚未执行的任务 executor.shutdownNow(); } /** * 第二章 线程池任务处理机制 * 来了一个任务后的处理机制 * 1、 当线程池线程数量小于corePoolSize时,立即新建一个线程执行任务; * 2、 当线程池线程数量等于corePoolSize,workQueue不满时,任务入workQueue队列,等待调度; * 3、 当workQueue满,线程池线程数量小于maximumPoolSize时,新建线程执行任务; * 4、 当线程池线程数量等于maximumPoolSize,workQueue满时,采用线程拒绝机制处理任务。 */ /** * 第三章 线程阻塞队列 * workQueue的类型为BlockingQueue<Runnable>,通常可以取下面三种类型: * 1、ArrayBlockingQueue:基于数组的先进先出队列,此队列创建时必须指定大小; * 2、LinkedBlockingQueue:基于链表的先进先出队列,如果创建时没有指定此队列大小,则默认为Integer.MAX_VALUE; * 3、synchronousQueue:这个队列比较特殊,它不会保存提交的任务,而是将直接新建一个线程来执行新来的任务。 */ /** * 第四章 线程拒绝机制 */ public void rejectedExecutionHandlerLearn() { // 丢弃任务并抛出RejectedExecutionException异常 handler = new ThreadPoolExecutor.AbortPolicy(); // 也是丢弃任务,但是不抛出异常 handler = new ThreadPoolExecutor.DiscardPolicy(); // 丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程) handler = new ThreadPoolExecutor.DiscardOldestPolicy(); // 由调用线程处理该任务 handler = new ThreadPoolExecutor.CallerRunsPolicy(); } /** * 第五章 JDK默认线程池 */ public void jdkThreadPool() { //创建一个缓冲池,缓冲池容量大小为Integer.MAX_VALUE Executors.newCachedThreadPool(); //创建容量为1的缓冲池 Executors.newSingleThreadExecutor(); //创建固定容量大小的缓冲池 Executors.newFixedThreadPool(5); } /** public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); } public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); } public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); } */ /** * 第六章 线程池大小设置 * 1、 如果是CPU密集型任务,就需要尽量压榨CPU,参考值可以设为 NCPU+1; * 2、 如果是IO密集型任务,参考值可以设置为2*NCPU。 */ /** * 第七章 JDK源码 * Creates a new {@code ThreadPoolExecutor} with the given initial * parameters. * * @param corePoolSize the number of threads to keep in the pool, even * if they are idle, unless {@code allowCoreThreadTimeOut} is set * @param maximumPoolSize the maximum number of threads to allow in the * pool * @param keepAliveTime when the number of threads is greater than * the core, this is the maximum time that excess idle threads * will wait for new tasks before terminating. * @param unit the time unit for the {@code keepAliveTime} argument * @param workQueue the queue to use for holding tasks before they are * executed. This queue will hold only the {@code Runnable} * tasks submitted by the {@code execute} method. * @param threadFactory the factory to use when the executor * creates a new thread * @param handler the handler to use when execution is blocked * because the thread bounds and queue capacities are reached * @throws IllegalArgumentException if one of the following holds:<br> * {@code corePoolSize < 0}<br> * {@code keepAliveTime < 0}<br> * {@code maximumPoolSize <= 0}<br> * {@code maximumPoolSize < corePoolSize} * @throws NullPointerException if {@code workQueue} * or {@code threadFactory} or {@code handler} is null public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) */ }