线程池的用法及思考
Posted cnxieyang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程池的用法及思考相关的知识,希望对你有一定的参考价值。
本文介绍下Java中线程池的基本用法,基于此说明如何去确定线程池的大小。
线程池的创建方法
newFixedThreadPool
创建固定线程数的线程池,见下创建代码
/** * Creates a thread pool that reuses a fixed number of threads * operating off a shared unbounded queue. At any point, at most * {@code nThreads} threads will be active processing tasks. * If additional tasks are submitted when all threads are active, * they will wait in the queue until a thread is available. * If any thread terminates due to a failure during execution * prior to shutdown, a new one will take its place if needed to * execute subsequent tasks. The threads in the pool will exist * until it is explicitly {@link ExecutorService#shutdown shutdown}. * * @param nThreads the number of threads in the pool * @return the newly created thread pool * @throws IllegalArgumentException if {@code nThreads <= 0} */ public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
从代码中可发现,corePoolSize和maxPoolSize都是相等的,取决于传入的线程数,keepAliveTime=0代表线程不进行超时回收,但使用的是无界队列,当任务数量过多时,将会导致OOM溢出。
newSingleThreadPool
创建线程数为1的线程池,创建代码如下。
/** * Creates an Executor that uses a single worker thread operating * off an unbounded queue. (Note however that if this single * thread terminates due to a failure during execution prior to * shutdown, a new one will take its place if needed to execute * subsequent tasks.) Tasks are guaranteed to execute * sequentially, and no more than one task will be active at any * given time. Unlike the otherwise equivalent * {@code newFixedThreadPool(1)} the returned executor is * guaranteed not to be reconfigurable to use additional threads. * * @return the newly created single-threaded Executor */ public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); } /** * 创建线程数为1的线程池 * */
我们发现corePoolSize和MaxPoolSize都是1,使用的还是无界队列,存在OOM
newCachedThreadPool
创建可缓存的线程池。代码如下
/** * Creates a thread pool that creates new threads as needed, but * will reuse previously constructed threads when they are * available. These pools will typically improve the performance * of programs that execute many short-lived asynchronous tasks. * Calls to {@code execute} will reuse previously constructed * threads if available. If no existing thread is available, a new * thread will be created and added to the pool. Threads that have * not been used for sixty seconds are terminated and removed from * the cache. Thus, a pool that remains idle for long enough will * not consume any resources. Note that pools with similar * properties but different details (for example, timeout parameters) * may be created using {@link ThreadPoolExecutor} constructors. * * @return the newly created thread pool */ public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
从创建代码中发现,corePoolSize核心线程数在一定时间内可以为零,当有一个新的任务时,只需要创建一个存活周期为60秒的线程,使用的是直接队列,队列任务为零,当任务过多时,会创建大量的线程,仍然会导致溢出。
newScheduledThreadPool
创建定义任务相关的线程数,在普通线程池的基础上引入了定时任务相关的操作。
/** * Creates a new {@code ScheduledThreadPoolExecutor} with the * given core pool size. * * @param corePoolSize the number of threads to keep in the pool, even * if they are idle, unless {@code allowCoreThreadTimeOut} is set * @throws IllegalArgumentException if {@code corePoolSize < 0} */ public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedWorkQueue()); }
我们发现可以指定核心线程数,maxPoolSize为Integer.MAX_VALUE,非核心线程数不进行回收,使用了延迟队列,也存在OOM
workStealingPool
jdk1.8新增的。产生递归操作时,可使用此线程池。
综上所述,提供了多种创建线程池的方法,具体使用哪种线程池方法,需要根据实际情况来定,使用多少线程数,最后通过性能测试去确定,我们也可以从CPU密集型和IO密集型方面进行简易区分。CPU密集型的线程数为CPU核心数的1到2倍。IO密集型线程数可为CPU核心数的10倍左右。
参考计算方法为:线程数=cpu核心数 * (1+ 平均等待时间/平均运行时间)
以上是关于线程池的用法及思考的主要内容,如果未能解决你的问题,请参考以下文章
newCacheThreadPool()newFixedThreadPool()newScheduledThreadPool()newSingleThreadExecutor()自定义线程池(代码片段