您的位置:

Android线程池详解

一、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() {
        // 执行任务
    }
});