必看5

精通 Android 多线程原理、线程池四种类型、自定义线程池

一、Android 多线程基础

1、Android 为什么不能在主线程做耗时操作?

答案

主线程负责 UI 绘制、事件响应;耗时会阻塞主线程,造成页面卡顿、掉帧 ,超过 5 秒会触发 ANR。

2、Android 更新 UI 为什么只能主线程?

答案

UI 控件不是线程安全的;

多线程同时操作会引发视图状态错乱、绘制异常;

Android 设计成单线程 UI 模型,只允许主线程更新。

3、子线程能不能直接更新 UI?有没有特例?

答案

正常不行;

特例:Activity 还没走完 onResume 之前,子线程可以临时更新 UI,上线不能依赖这种写法

4、Android 常用多线程方式有哪些?

答案

Thread、Runnable、AsyncTask(废弃)、Handler、IntentService(废弃)、线程池、Coroutine 协程、RxJava。

二、线程池核心基础

1、为什么要用线程池?不直接 new Thread?

答案

  1. 频繁创建销毁线程开销大、容易 GC 卡顿
  2. 线程无限制新建,容易线程泛滥、OOM
  3. 线程池复用线程、控制并发数、队列管理任务、统一调度

2、线程池七大核心参数是什么?

答案

  1. corePoolSize:核心线程数(常驻不回收)
  2. maximumPoolSize:最大线程数
  3. keepAliveTime:非核心线程空闲超时回收时间
  4. unit:超时时间单位
  5. workQueue:任务阻塞队列,存放等待执行的任务
  6. threadFactory:线程工厂
  7. handler: 拒绝策略

线程池七大参数:核心线程数、最大线程数、空闲超时、时间单位、阻塞队列、线程工厂、拒绝策略;

3、线程池任务执行流程?

答案

  1. 来了任务,核心线程数没满 → 新建核心线程执行
  2. 核心线程已满 → 任务进队列排队
  3. 队列已满 → 新建非核心线程
  4. 达到最大线程数仍处理不过来 → 触发拒绝策略

三、Java 四种内置线程池

1、Executors.newFixedThreadPool 固定线程池

答案

  • 核心线程 = 最大线程,固定并发数
  • 无空闲回收,队列无界
  • 适合:批量后台任务、网络请求

2、Executors.newSingleThreadExecutor 单线程池

答案

  • 始终只有1 个线程,任务串行排队执行
  • 适合:顺序执行任务、日志写入、本地 IO 串行操作

3、Executors.newCachedThreadPool 缓存线程池

答案

  • 无核心线程,最大线程无限制
  • 空闲 60 秒自动回收
  • 任务多就无限建新线程,容易 OOM
  • 适合:大量短时异步任务

4、Executors.newScheduledThreadPool 定时线程池

答案

  • 支持延时执行、周期重复执行
  • 适合:轮询任务、定时刷新、心跳检测

5、阿里开发规范为什么禁止用 Executors 创建线程池?

答案

  1. 部分线程池任务队列无界,任务堆积引发 OOM
  2. 部分最大线程无限制,线程泛滥 OOM
  3. 无法自定义拒绝策略、参数不透明

规范:必须自己通过 ThreadPoolExecutor 手动创建

四、自定义线程池

1、怎么自定义线程池?

答案

直接 new ThreadPoolExecutor,

手动指定:核心线程数、最大线程数、超时时间、阻塞队列、自定义线程工厂、拒绝策略。

2、常用阻塞队列有哪些?

答案

  • ArrayBlockingQueue:有界数组队列
  • LinkedBlockingQueue:可有界 / 无界链表队列
  • SynchronousQueue:不缓存任务,直接交付线程

3、四种拒绝策略

答案

  1. AbortPolicy:默认,直接抛异常
  2. CallerRunsPolicy:交给调用者线程自己执行
  3. DiscardPolicy:直接丢弃当前任务,不报错
  4. DiscardOldestPolicy:丢弃队列最旧任务,执行新任务

4、自定义线程池好处?

答案

参数可控、队列有界防 OOM、自定义线程名便于日志排查、自定义拒绝策略适配业务、性能更稳定。

五、面试一句话

Android 主线程禁止耗时防止卡顿和 ANR,UI 非线程安全只能主线程更新;

线程池复用线程、控制并发避免频繁创建 Thread;

四大内置线程池各有场景但阿里禁止直接使用,容易无界队列和无限线程导致 OOM;

实际开发用ThreadPoolExecutor 手动自定义线程池,配置核心参数、有界队列、自定义线程工厂和拒绝策略,稳定可控易排查。

相关推荐
火柴就是我3 小时前
Flutter 项目本地 Maven 引入 AAR 找不到?一次 Gradle 路径问题排查
android
火柴就是我3 小时前
Android 打包报错 25.0.3
android·前端
码上有光4 小时前
Linux进程通信——共享内存、消息队列和信号量
android·linux·运维·共享内存·通信
Android打工仔8 小时前
Kotlin 协程源码解析:DispatchedContinuation 里的 Dispatcher 从哪里来?
android·kotlin
打工仔折腾 AI8 小时前
从BPE到SentencePiece:Transformer分词原理与Python实战对比
android·人工智能·python·深度学习·langchain·transformer·ai agent 实战
Dovis(誓平步青云)9 小时前
几个方案来回选不定?做一个随时切换的候选推荐页
android·java·服务器·开发语言·javascript·数据库·智能化
恋猫de小郭12 小时前
KMP 又改了编译流程, Separate Compilation 禁止了 `commonMain` 的依赖穿透
android·前端·flutter
执明wa13 小时前
Android RecyclerView 实战:点击频道栏切换对应内容
android·开发语言·windows·microsoft·android studio
新鲜势力呀13 小时前
PHP 定时数据同步实战:从第三方接口超时到异步同步 + 增量更新架构优化全过程
android
星间都市山脉15 小时前
RecoveryUI 圆角屏安全边距配置及代码调用链
android·java·linux·windows·ubuntu