线程池创建方式
线程池创建通常有两种方式
- 手动new ThreadPoolExecutor 根据需求进行配置。
- 使用ExecutorService工厂进行配置。
线程池的分类
- FixThreadPool
通过ExecutorService的newFixedThreadPool方法来创建。
/**
* Creates a thread pool that reuses a fixed number of threads
* operating off a shared unbounded queue, using the provided
* ThreadFactory to create new threads when needed. 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
* @param threadFactory the factory to use when creating new threads
* @return the newly created thread pool
* @throws NullPointerException if threadFactory is null
* @throws IllegalArgumentException if {@code nThreads <= 0}
*/
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory);
}
注释说的是比较清晰的。这个线程池的线程数量是固定的,核心线程和总的线程数都是核心线程数,那么就说明这个线程池中只有核心线程,那么由于核心线程是一直存活的,那所提交的任务如果小于核心线程数就会立即得到执行,所以响应的速度是比较高的。阻塞队列用的是无界的,如果所有的核心线程都在占用,那么提交的任务全部都会插入到阻塞队列中。
- CachedPoolThread
通过ExecutorService的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>());
}
这个线程池没有核心线程,会按需创建线程,但是会重用处于空闲状态的线程。同时阻塞队列是SynchronousQueue,它无法存储元素,所以提交的任务都会被执行。因为maximumPoolSize为 Integer.MAX_VALUE特别大,所以基本上提交的任务都会立即执行。超时限制为6线程就0s,所以如果60s后如果没有新的任务到来,那么会被terminated,所以如果线程池长时间没有任务,那么所有的线程都会被销毁,那么就不会消耗资源。
CachedPoolThread适用于执行大量耗时较短的任务。
应用场景:Okhttp的网络请求
public final class Dispatcher {
/** Executes calls. Created lazily. */
private @Nullable ExecutorService executorService;
public synchronized ExecutorService executorService() {
if (executorService == null) {
executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
}
return executorService;
}
}
- ScheduledThreadPool
通过ExecutorService的newCachedThreadPool来创建。
/**
* 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
* @param threadFactory the factory to use when the executor
* creates a new thread
* @return a newly created scheduled thread pool
* @throws IllegalArgumentException if {@code corePoolSize < 0}
* @throws NullPointerException if threadFactory is null
*/
public static ScheduledExecutorService newScheduledThreadPool(
int corePoolSize, ThreadFactory threadFactory) {
return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory);
}
public ScheduledThreadPoolExecutor(int corePoolSize,
ThreadFactory threadFactory) {
super(corePoolSize, Integer.MAX_VALUE,
DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
new DelayedWorkQueue(), threadFactory);
}
它用于执行定时任务或者周期性任务,有固定的核心线程数,非核心线程数会在超过空闲时间后回收。
应用场景:RxJava中
如在SchedulerPoolFactory.java中
public class NewThreadWorker extends Scheduler.Worker implements Disposable {
private final ScheduledExecutorService executor;
public NewThreadWorker(ThreadFactory threadFactory) {
executor = SchedulerPoolFactory.create(threadFactory);
}
** SchedulerPoolFactory.java**
/**
* Creates a ScheduledExecutorService with the given factory.
* @param factory the thread factory
* @return the ScheduledExecutorService
*/
public static ScheduledExecutorService create(ThreadFactory factory) {
** 注意这里**
final ScheduledExecutorService exec = Executors.newScheduledThreadPool(1, factory);
tryPutIntoPool(PURGE_ENABLED, exec);
return exec;
}
- SingleThreadPool
通过ExecutorService的newSingleThreadExecutor来创建。
/**
* 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,最大线程数为1,所以同一时刻只有1个任务运行,阻塞队列为无界队列,按序插入,也只能按序取出执行,所以该线程池实现了任务的顺序执行。因而不需要处理同步问题。