一、Android线程池的使用
Executor executor = Executors.newFixedThreadPool(3);
executor.execute(new Runnable() {
@Override
public void run() {
// 执行任务
}
});
Android线程池通常使用Executor接口的实现类来创建。线程池是一个可以根据实际情况调整线程数量的线程集合。线程池会复用已有线程,减少线程的创建和销毁,提高了线程资源的利用率。
二、Android线程池使用场景
Android线程池常用于以下几个场景:
- 多线程下载任务
- 多线程数据加密/解密
- 后台数据同步任务
- 网络请求任务
三、Android线程池原理
Android线程池实际上是一种线程复用的设计模式。线程池中维护了一定数量的线程,并将这些线程存入一个等待队列中。当有新的任务来到时,线程池就会从等待队列中选择一个线程来执行该任务,随后在等待队列中加入一个新的任务。
四、Android线程池启动
ExecutorService executorService = Executors.newFixedThreadPool(3);
executorService.execute(new Runnable() {
@Override
public void run() {
// 执行任务
}
});
// 线程池停止
executorService.shutdown();
启动线程池通常使用ExecutorService接口的实现类来创建。ExecutorService接口是Executor接口的子接口,增加了一些监控线程池的方法(如isShutdown()、isTerminated()等)。
五、Android线程池代理
Android线程池代理是一种AOP编程思想,使用代理对象来控制目标对象(线程)的访问,实现横向业务逻辑的处理。通过线程池代理,可以在线程执行前后做一些特定的操作(如打印日志、记录执行时间等)。
六、Android线程池有几种
Android线程池有四种类型:
- FixedThreadPool固定线程池
- CachedThreadPool缓存线程池
- ScheduledThreadPool定时线程池
- SingleThreadExecutor单线程池
七、Android线程池工作在哪个线程
Android线程池本身是由一个线程集合或线程池来执行任务,这个线程集合中的线程是由操作系统中的内核线程来实现的。所以线程池实际上是工作在操作系统的内核线程中。
八、Android线程池统一
在Android中,可以通过ThreadPoolExecutor来统一管理线程池,例如:
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
10, // 核心线程数
20, // 最大线程数
60, // 空闲线程存活时间
TimeUnit.SECONDS, // 时间单位
new ArrayBlockingQueue<>(10), // 任务等待队列
Executors.defaultThreadFactory(), // 线程工厂
new ThreadPoolExecutor.AbortPolicy() // 任务拒绝处理器
);
threadPoolExecutor.execute(new Runnable() {
@Override
public void run() {
// 执行任务
}
});
九、Android线程池面试题
1、线程池中的常见拒绝策略有哪些?
有四种拒绝策略:AbortPolicy(用于丢弃任务并抛出异常)、DiscardPolicy(用于丢弃任务但不抛出异常)、DiscardOldestPolicy(用于丢弃队列中最老的任务,然后重新添加新任务)和CallerRunsPolicy(用于在主线程中执行任务)。
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
10, // 核心线程数
20, // 最大线程数
60, // 空闲线程存活时间
TimeUnit.SECONDS, // 时间单位
new ArrayBlockingQueue<>(10), // 任务等待队列
Executors.defaultThreadFactory(), // 线程工厂
new ThreadPoolExecutor.DiscardOldestPolicy() // 任务拒绝处理器
);
2、线程池会出现哪些问题?应该如何避免?
线程池可能出现以下问题:
- 线程数量不足或过多
- 队列太小导致任务堆积
- 线程池过早终止任务导致任务被丢失
为了避免这些问题,需要根据实际情况选择适当的线程池类型、设置合理的核心线程数和队列大小,并在关闭线程池时调用shutdown()方法。
十、Android线程池hook
线程池hook是一种通过代理对象来控制目标线程池的访问的AOP编程思想,通过hook技术可以在线程池执行前后做一些特定的操作(如记录执行时间、打印日志等)。
public class MyThreadPool extends ThreadPoolExecutor {
public MyThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
}
@Override
protected void beforeExecute(Thread t, Runnable r) {
super.beforeExecute(t, r);
System.out.println("线程池执行任务前,当前线程数:" + this.getActiveCount());
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
System.out.println("线程池执行任务后,当前线程数:" + this.getActiveCount());
}
}
MyThreadPool threadPool = new MyThreadPool(10, 20, 60, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(10),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
threadPool.execute(new Runnable() {
@Override
public void run() {
// 执行任务
}
});