线程池三问—百度真题
Posted 码上积木
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程池三问—百度真题相关的知识,希望对你有一定的参考价值。
线程分为主线程和子线程,主线程用于处理界面相关事情,子线程用于执行耗时操作。所以子线程的任务管理就格外重要,线程池就是这个管理的角色。今天的三问是关于线程池的:
-
线程池是干嘛的,优点有哪些? -
线程池的构造方法每个参数是什么意思,执行任务的流程 -
android线程池主要分为哪几类,分别代表了什么?
线程池是干嘛的,优点有哪些?
线程池主要用作管理子线程,优点有:
-
重用线程池中的线程,避免频繁创建和销毁线程所带来的 内存开销
。 -
有效控制线程的最大并发数,避免因线程之间抢占资源而导致的 阻塞现象
。 -
能够对线程进行简单的管理,提供 定时执行
以及指定时间间隔循环执行
等功能。
线程池的构造方法每个参数是什么意思,执行任务的流程
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {}
-
corePoolSize
:核心线程数。默认情况下线程池是空的,只是任务提交时才会创建线程。如果当前运行的线程数少于corePoolSize,则会创建新线程来处理任务;如果等于或者等于corePoolSize,则不再创建。如果调用线程池的prestartAllcoreThread方法,线程池会提前创建并启动所有的核心线程来等待任务。 -
maximumPoolSize
:线程池允许创建的最大线程数。如果任务队列满了并且线程数小于maximumPoolSize时,则线程池仍然会创建新的线程来处理任务。 -
keepAliveTime
:非核心线程闲置的超时事件。超过这个事件则回收。如果任务很多,并且每个任务的执行时间很短,则可以调大keepAliveTime来提高线程的利用率。另外,如果设置allowCoreThreadTimeOut属性来true时,keepAliveTime也会应用到核心线程上。 -
TimeUnit
:keepAliveTime参数的时间单位。可选的单位有天Days、小时HOURS、分钟MINUTES、秒SECONDS、毫秒MILLISECONDS等。 -
workQueue
:任务队列。如果当前线程数大于corePoolSzie,则将任务添加到此任务队列中。该任务队列是BlockingQueue类型的,即阻塞队列。 -
ThreadFactory
:线程工厂。可以使用线程工厂给每个创建出来的线程设置名字。一般情况下无须设置该参数。 -
RejectedExecutionHandler
:拒绝策略。这是当前任务队列和线程池都满了时所采取的应对策略,默认是AbordPolicy,表示无法处理新任务,并抛出RejectedExecutionException异常。
其中,拒绝策略有四种:
-
AbordPolicy
:无法处理新任务,并抛出RejectedExecutionException异常。 -
CallerRunsPolicy
:用调用者所在的线程来处理任务。此策略提供简单的反馈控制机制,能够减缓新任务的提交速度。 -
DiscardPolicy
:不能执行的任务,并将该任务删除。 -
DiscardOldestPolicy
:丢弃队列最近的任务,并执行当前的任务。
执行任务流程:
-
如果线程池中的线程数量未达到 核心线程的数量
,会直接启动一个核心线程来执行任务。 -
如果线程池中的线程数量已经达到或者超过核心线程的数量,那么任务会被插入到 任务队列
中排队等待执行。 -
如果任务队列无法插入新任务,说明任务队列已满,如果未达到规定的最大线程数量,则启动一个 非核心线程
来执行任务。 -
如果线程数量超过规定的最大值,则执行 拒绝策略
-RejectedExecutionHandler。
Android线程池主要分为哪几类,分别代表了什么?
主要有四类:FixedThreadPool、CachedThreadPool、SingleThreadExecutor、ScheduledTheadPool
1) FixedThreadPool——可重用固定线程数的线程池
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
-
线程 数量固定
且都是核心线程:核心线程数量和最大线程数量都是nThreads; -
都是核心线程且不会被回收,快速相应外界请求; -
没有超时机制,任务队列也没有大小限制; -
新任务使用 核心线程
处理,如果没有空闲的核心线程,则排队等待执行。
-
CachedThreadPool——按需创建的线程池
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
-
线程数量不定,只有非核心线程,最大线程数 任意大
:传入核心线程数量的参数为0,最大线程数为Integer.MAX_VALUE; -
有新任务时使用 空闲线程
执行,没有空闲线程则创建新的线程来处理。 -
该线程池的每个空闲线程都有超时机制,时常为60s(参数:60L, TimeUnit.SECONDS),空闲超过60s则回收空闲线程。 -
适合执行大量的耗时较少的任务,当所有线程闲置 超过60s
都会被停止,所以这时几乎不占用系统资源。
-
SingleThreadExecutor——单线程的线程池
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
-
只有 一个核心线程
,所有任务在同一个线程按顺序执行。 -
所有的外界任务统一到一个线程中,所以不需要处理线程同步的问题。
-
ScheduledThreadPool——定时和周期性的线程池
private static final long DEFAULT_KEEPALIVE_MILLIS = 10L;
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE,
DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
new DelayedWorkQueue());
}
-
核心线程 数量固定
,非核心线程数量无限制
; -
非核心线程闲置超过10s会被回收; -
主要用于执行定时任务和具有固定周期的重复任务;
参考链接
线程池讲解
以上是关于线程池三问—百度真题的主要内容,如果未能解决你的问题,请参考以下文章