💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
#### 11.3.2 线程池的分类 在11.3.1节中对ThreadPoolExecutor的配置细节进行了详细的介绍,本节将接着介绍**Android中最常见的四类具有不同功能特性的线程池,它们都直接或间接地通过配置ThreadPoolExecutor来实现自己的功能特性**,这四类线程池分别是**FixedThreadPool、CachedThreadPool、ScheduledThreadPool以及SingleThreadExecutor**。 在JDK 的java.util.concurrent.Executors 中提供了生成多种线程池的静态方法,然后调用他们的execute 方法即可。 ``` ExecutorService newCachedThreadPool = Executors.newCachedThreadPool(); ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(4); ScheduledExecutorService newScheduledThreadPool =Executors.newScheduledThreadPool(4); ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor(); ``` * [ ] 1、**FixedThreadPooI** 通过[Executors](https://www.androidos.net.cn/android/6.0.1_r16/xref/libcore/luni/src/main/java/java/util/concurrent/Executors.java)的`newFixedThreadPool`方法来创建。它是一种**线程数量固定的线程池**, * 当**线程处于空闲状态时,它们并不会被回收,除非线程池被关闭了**。 * 当**所有的线程都处于活动状态时,新任务都会处于等待状态,直到有线程空闲出来**。 由于**FixedThreadPool只有核心线程并且这些核心线程不会被回收**,这意味着**它能够更加快速地响应外界的请求**。newFixedThreadPool方法的实现如下,可以发现**FixedThreadPool中只有核心线程并且这些核心线程没有超时机制,另外任务队列也是没有大小限制**的。 ``` public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); } ``` * [ ] 2、**CachedThreadPooI** 通过Executors的`newCachedThreadPool`方法来创建。 它是一种**线程数量不定的线程池,它只有非核心线程,并且其最大线程数为`Integer.MAX_VALUE`**。由于`Integer.MAX_VALUE`是一个很大的数,实际上就**相当于最大线程数可以任意大**。 **当线程池中的线程都处于活动状态时,线程池会创建新的线程来处理新任务,否则就会利用空闲的线程来处理新任务。线程池中的空闲线程都有超时机制,这个超时时长为60秒,超过60秒闲置线程就会被回收**。 和FixedThreadPool不同的是,**CachedThreadPool的任务队列其实相当于一个空集合,这将导致任何任务都会立即被执行,因为在这种场景下SynchronousQueue是无法插入任务的**。 *SynchronousQueue是一个非常特殊的队列,在很多情况下可以把它简单理解为一个无法存储元素的队列,由于它在实际中较少使用,这里就不深入探讨它了*。从**CachedThreadPoo**l的特性来看,这类线程池**比较适合执行大量的耗时较少的任务。当整个线程池都处于闲置状态时,线程池中的线程都会超时而被停止,这个时候CachedThreadPool之中实际上是没有任何线程的,它几乎是不占用任何系统资源的**。newCachedThreadPool方法的实现如下所示。 ``` public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); } ``` * 3、**ScheduIedThreadPooI** 通过Executors的`newScheduledThreadPool`方法来创建。它的**核心线程数量是固定的,而非核心线程数是没有限制的,并且当非核心线程闲置时会被立即回收**。ScheduledThreadPool这类线程池**主要用于执行定时任务和具有固定周期的重复任务**,newScheduledThreadPool方法的实现如下所示。 ``` public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { return new ScheduledThreadPoolExecutor(corePoolSize); } public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,new DelayedWorkQueue()); } ``` * 4、**SingIeThreadExecutor** 通过Executors的`newSingleThreadExecutor`方法来创建。这类**线程池内部只有一个核心线程,它确保所有的任务都在同一个线程中按顺序执行**。SingleThreadExecutor的**意义在于统一所有的外界任务到一个线程中,这使得在这些任务之间不需要处理线程同步的问题**。newSingleThreadExecutor方法的实现如下所示。 ``` public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); } ``` 上面对Android中常见的4种线程池进行了详细的介绍,除了上面系统提供的4类线程池以外,也可以根据实际需要灵活地配置线程池。下面的代码演示了系统预置的4种线程池的典型使用方法。 ``` Runnable command = new Runnable() { @Override public void run() { SystemClock.sleep(2000); } }; ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4); fixedThreadPool.execute(command); ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); cachedThreadPool.execute(command); ScheduledExecutorService scheduledThreadPool=Executors.newScheduledThreadPool(4); // 2000ms后执行command scheduledThreadPool.schedule(command, 2000, TimeUnit.MILLISECONDS); // 延迟10ms后,每隔1000ms执行一次command scheduledThreadPool.scheduleAtFixedRate(command, 10, 1000, TimeUnit.MILLISECONDS); ExecutorService singleThreadExecutor =Executors.newSingleThreadExecutor(); singleThreadExecutor.execute(command); ```