--------在java中,提供了使用Executors获取线程池,但是使用Executors获取线程池可能会出现问题,常用的几种线程池有以下几种:
-
CachedThreadPool
创建一个可缓冲的线程池,如果线程数大于任务数,则灵活回收,若小于,则新建线程,由于数量最大为Integer的最大值,因此线程池的大小完全依赖于操作系统(JVM)能够创建的最大线程大小。 -
FixedThreadPool
创建一个定长线程池,可控制线程最大并发数,超出线程个数会在队列中等待。 -
ScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行。 -
SingleThreadExecutor
创建一个单线程的线程池,它只会用唯一的工作线程来执行任务,保证所有的任务按照指定的数据(FIFO,LIFO,优先级)执行。
但是一般我们是通过ThreadPoolExecutor构建线程池对象的,不会使用Executors静态工厂类创建线程池的,原因是Executors返回的线程池有弊端:
① FixedThreadPool和SingleThreadExecutor:允许的任务队列长度是Integer.MAX_VALUE,可能会堆积大量的任务,导致OOM
②CachedThreadPool:允许的线程数量是Integer.MAX_VALUE,可能会创建大量的线程,导致OOM
- ThreadPoolExecutor
/** * 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) { }
参数说明:corePoolSize---核心线程数,线程池最低的线程数
maximumPoolSize---允许的最大的线程数
keepAliveTime---当前线程数超过corePoolSize的时候,空闲线程保留的时间
unit---keepAliveTime的时间单位
workQueue---任务缓冲队列
threadFactory---线程的构造工厂
handler---线程池饱含时候的处理策略
-
CachedThreadPool
/** * 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为0,maximumPoolSize为无限大,意味着线程数量可以无限大
③采用SynchronousQueue队列装等待任务,这个阻塞队列没有存储空间,意味着只要有任务到来,必须要找到一个工作线程处理它,如果当前没有空闲的线程,就需要新建线程。
-
FixedThreadPool
/** * 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和maximumPoolSize都为设定的线程数量nThreads
②keepAliveTime为0,意味着一旦有多余的空闲线程,就会被立即停掉,但是这里的keepAliveTime无效
③采用LinkedBlockingQueue阻塞队列,它是个无界队列,因此永远不可能拒绝任务。
④由于采用无界队列,并且maximumPoolSize和keepAliveTime都无效,线程实际数目永远维持在nThreads
-
ScheduledThreadPool
/** * Creates a thread pool that can schedule commands to run after a * given delay, or to execute periodically. * @param corePoolSize the number of threads to keep in the pool, * even if they are idle * @return a newly created scheduled thread pool * @throws IllegalArgumentException if {@code corePoolSize < 0} */ public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize); } /** * 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()); }
定时任务,最大线程数量为Integer的最大值。
-
SingleThreadExecutor
/** * 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
②阻塞队列采用LinkedBlockingQueue