Android中的线程池及使用

本文详细介绍了Android中四种线程池的应用场景与实现方式,包括定长线程池、定时线程池、可缓存线程池和单线程化线程池。并提供了okhttp和rxjava中线程池的具体实现案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android中的线程池及使用

线程池能处理业务中多个线程并发的问题,避免大量产生新的线程相互抢占系统资源,可以统一通过线程池来配置不同参数来管理线程。java中已经内置好了四种线程池供我们使用。


  • 线程池创建的参数
    corePoolSize 核心线程数 一般情况下一直存活,即使没有任务

  • maximumPoolSize 最大线程池数量

    keepAliveTime 非核心线程的闲置时长 当非核心线程的空闲时间超过该时长,会被回收节省资源,当设置allowCoreThreadTimeOut为true时候,核心线程也会被该规则回收

    TimeUnit 指定keepAliveTime的时间单位

    BlockingQueue 线程池的任务队列 通过execute(Runnable command)方法将任务放入队列中

    ThreadFactory 线程工厂 是一个接口 Thread newThread(Runnable var1)用来创建新的线程

    RejectedExecutionHandler 线程池对拒绝任务的处理策略 当线程池满了或者产生其他异常,对未进入线程池的任务进行大的处理策略,可以不用传,有默认值。


JAVA中已经为我们提供了四种参数设置好的线程池

  • 定长线程池 FixedThreadPool
  //nThreads  核心线程数
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);
        //执行任务
        fixedThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                Log.e("tag","执行任务");
            }
        });
        //关闭线程池
        fixedThreadPool.shutdown();

特点:指定一个一定数量的工作线程的线程池,可以节省线程创建的时间提高使用效率,当工作线程达到最大线程数数量,新的任务会进入等待队列。但是当线程池空闲时候,空闲线程也不会销毁,因为创建的只为核心线程。

  • 定时线程池 ScheduledThreadPScheduledExecutorService
 ScheduledExecutorService scheduledExecutorService =
                Executors.newScheduledThreadPool(5);
        scheduledExecutorService.schedule(new Runnable() {
            @Override
            public void run() {
                Log.e("tag", "延迟2秒再提交任务");
            }
        }, 2, TimeUnit.SECONDS);
        scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
            @Override
            public void run() {
                Log.e("tag", "延迟2秒后,每隔1秒执行任务");
            }
        }, 2, 1, TimeUnit.SECONDS);
        scheduledExecutorService.shutdown();

特点:指定一个指定数量的核心线程数,非核心线程数无限制。支持定时延迟执行任务和周期性执行任务。没超过核心线程数情况可减少线程创建时间,超过会新建工作线程,闲置时候会被马上回收。

  • 可缓存线程池 CachedThreadPool
ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                Log.e("执行任务","执行任务");
            }
        });
        executorService.shutdown();

特点:没有核心线程数,非核心线程可无限扩大,使用灵活,空闲线程也会被即时回收。任何线程任务提交是,会被立即执行,无需等待。

  • 单线程化线程池 SingleThreadExecutor
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
        singleThreadExecutor.execute(new Runnable() {
            @Override
            public void run() {
                Log.e("tag","执行任务");
            }
        });
        singleThreadExecutor.shutdown();

特点:只创建一个唯一的核心线程来工作,所有任务按照(先进先出,后进先出)的规则执行。可解决银行存钱取钱模型问题,同时保证线程安全,数据不会错乱。


几个大库使用的线程池:

  • okhttp使用线程池,代码如下:

创建非核心线程为无限大,实际上受maxRequests(默认值为65)影响。

 public synchronized ExecutorService executorService() {
    if (executorService == null) {
      executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
          new SynchronousQueue<Runnable>(), Util.threadFactory("OkHttp Dispatcher", false));
    }
    return executorService;
  }
synchronized void enqueue(AsyncCall call) {
    if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
      runningAsyncCalls.add(call);
      executorService().execute(call);
    } else {
      readyAsyncCalls.add(call);
    }
  }
  • rxjava中的线程池的使用
    io工作线程,创建定长线程。
CachedWorkerPool(long keepAliveTime, TimeUnit unit, ThreadFactory threadFactory) {
            this.keepAliveTime = unit != null ? unit.toNanos(keepAliveTime) : 0L;
            this.expiringWorkerQueue = new ConcurrentLinkedQueue<ThreadWorker>();
            this.allWorkers = new CompositeDisposable();
            this.threadFactory = threadFactory;

            ScheduledExecutorService evictor = null;
            Future<?> task = null;
            if (unit != null) {
                evictor = Executors.newScheduledThreadPool(1, EVICTOR_THREAD_FACTORY);
                task = evictor.scheduleWithFixedDelay(this, this.keepAliveTime, this.keepAliveTime, TimeUnit.NANOSECONDS);
            }
            evictorService = evictor;
            evictorTask = task;
        }

自己简单的封装

public class ThreadPoolManager {

    private long keepAliveTime = 10;//存活时间
    private TimeUnit unit = TimeUnit.MINUTES;
    private final ThreadPoolExecutor mThreadPoolExecutor;

    //静态内部类,
    private static class HelperSinger{
        private static ThreadPoolManager sSingletonTest = new ThreadPoolManager();
    }

    private ThreadPoolManager(){
        int corePoolSize = Runtime.getRuntime().availableProcessors()*2+1;
        int maxmunPoolSize = corePoolSize;
        //LinkedBlockingQueue  先进先去
        //defaultThreadFactory  线程工厂
        //AbortPolicy  队列满额的拒绝策略
        mThreadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maxmunPoolSize,
                keepAliveTime, unit, new LinkedBlockingQueue<>(),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());

    }

    public static ThreadPoolManager getInstace(){
        return HelperSinger.sSingletonTest;
    }

    public void execute(Runnable runnable){
        if(runnable==null)return;

        mThreadPoolExecutor.execute(runnable);
    }
    /**
     * 从线程池中移除任务
     */
    public void remove(Runnable runnable){
        if(runnable==null)return;
        mThreadPoolExecutor.remove(runnable);
    }


    public void shutDown(Runnable runnable){
        if(mThreadPoolExecutor.isShutdown())return;
        mThreadPoolExecutor.shutdown();
    }
}

总结:多看其他库的源码(okhttp,rxjava,fresco),里面都有用到线程池,而且用的很深,看不懂。

<think>好的,我现在需要帮助用户了解Android线程池的实现机制,特别是Executor Framework。首先,用户的问题是关于Android线程池的实现方式,提到了Executor Framework,所以我应该重点围绕这个部分展开。 首先,我需要回忆一下Android线程池的相关知识。记得Android中的线程池主要是通过java.util.concurrent包中的Executor Framework来实现的,这个框架提供了一系列的线程池创建和管理工具。可能涉及到ThreadPoolExecutor这个核心类,以及Executors工厂类提供的几种预定义线程池,比如FixedThreadPool、CachedThreadPool、SingleThreadExecutor等。 接下来,用户给的参考引用中有四个来源,其中引用[1]和[2]提到了使用ExecutorService、AsyncTask和Runnable来实现线程池。而引用[3]和[4]是关于SpringBoot和SpringCloud的,可能和Android无关,但需要确认是否有相关的内容可以借鉴,不过可能用户是误贴了这些内容,或者需要排除干扰。因此,我应该主要关注引用[1]和[2]的内容。 用户的问题还要求回答结构清晰,分步骤说明,并且生成相关问题。同时需要遵循系统级指令中的格式要求,比如数学公式的格式,引用标识的正确使用等。 首先,我应该解释Executor Framework在Android中的实现机制。可能需要分点说明,比如核心组件、线程池类型、任务提交方式、线程池参数等。然后结合代码示例,比如如何使用ExecutorService来创建线程池,执行任务。同时,用户提供的引用中有AsyncTask,虽然现在可能已经被弃用,但可能需要提到,并说明推荐的方式。 然后,需要确保代码示例正确,并且符合用户提供的引用中的方式一,即主类文件使用ExecutorService、AsyncTask、Runnable。但AsyncTask在Android中已经过时,可能需要指出,并建议使用ExecutorService配合Handler或者LiveData来更新UI。 另外,需要检查LaTeX语法是否正确,但用户的问题中可能不涉及数学公式,不过如果有任何公式,比如参数说明中的核心数、队列容量等,可能需要用行内公式格式。 在回答过程中,需要自然地添加引用标识,比如在提到ExecutorService的时候,引用用户提供的引用[1]和[2],但需要确保引用的内容确实相关。例如,引用[1]提到的是Android线程池的经典使用方式,包括ExecutorService、AsyncTask、Runnable,这正好符合用户的问题。 可能需要注意,用户提供的引用[3]和[4]是关于SpringBoot和SpringCloud的,可能与当前问题无关,可以忽略,或者在生成相关问题的时候,如果涉及到其他框架的线程池,可以生成相关问题,但需要明确区分Android和Spring的上下文。 现在,我需要组织回答的结构: 1. 概述Executor Framework在Android中的作用。 2. 核心组件:ThreadPoolExecutor和Executors工厂类。 3. 四种预定义线程池类型及其适用场景。 4. 自定义线程池的参数配置。 5. 结合代码示例说明如何使用ExecutorService提交任务。 6. 提到AsyncTask的过时,推荐使用Executor配合其他机制更新UI。 7. 引用相关站内引用,例如方式一的实现。 同时,生成相关问题,比如线程池参数如何配置、不同线程池的适用场景、AsyncTask的替代方案等。 需要确保回答符合中文,使用正确的术语,避免技术错误,比如不混淆ThreadPoolExecutor和Executors的关系,正确解释各参数的意义。 最后,检查是否符合系统级指令中的格式要求,例如代码块使用正确的语法,引用标识正确放置,没有使用Markdown格式,段落清晰,分点说明等。</think>### Android线程池实现机制(Executor Framework) Android通过Java的`java.util.concurrent`包提供**Executor框架**实现线程池管理,其核心组件是`ThreadPoolExecutor`和`Executors`工厂类。以下为关键实现机制: --- #### 1. **核心组件** - **`ThreadPoolExecutor`** 直接控制线程池参数,包括: - **核心线程数**($corePoolSize$):常驻线程数量 - **最大线程数**($maxPoolSize$):线程池可扩展的最大上限 - **任务队列**($workQueue$):存储待执行任务(如`LinkedBlockingQueue`) - **线程存活时间**($keepAliveTime$):非核心线程空闲时的存活时长[^1] - **`Executors`工厂类** 提供预定义线程池类型,简化创建过程: ```java ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4); // 固定大小线程池 ``` --- #### 2. **Android中的线程池类型** | 类型 | 特点 | 适用场景 | |-----------------------|----------------------------------------------------------------------|------------------------| | **FixedThreadPool** | 固定核心线程数,无超时机制 | CPU密集型任务 | | **CachedThreadPool** | 线程数动态扩展,空闲线程自动回收 | 短期异步任务 | | **SingleThreadPool** | 单一线程顺序执行任务 | 需顺序执行的任务队列 | | **ScheduledThreadPool** | 支持定时或周期性任务 | 定时/延迟任务 | --- #### 3. **任务提交方式** - **`Runnable`接口**:无返回值任务 ```java executorService.execute(new Runnable() { @Override public void run() { // 后台逻辑 } }); ``` - **`Callable`接口**:支持返回结果 ```java Future<String> future = executorService.submit(new Callable<String>() { @Override public String call() throws Exception { return "Result"; } }); ``` --- #### 4. **自定义线程池示例** 通过`ThreadPoolExecutor`配置参数: ```java int corePoolSize = 2; int maxPoolSize = 5; long keepAliveTime = 30L; TimeUnit unit = TimeUnit.SECONDS; BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(10); ThreadPoolExecutor executor = new ThreadPoolExecutor( corePoolSize, maxPoolSize, keepAliveTime, unit, workQueue ); executor.execute(task); // 提交任务 ``` --- #### 5. **与UI线程的交互** - **`AsyncTask`(已过时)**:早期用于后台任务与UI更新,但易引发内存泄漏[^2]。 - **推荐方式**:使用`ExecutorService`配合`Handler`或`LiveData`更新UI: ```java executor.execute(() -> { // 后台计算 String result = processData(); new Handler(Looper.getMainLooper()).post(() -> { textView.setText(result); // 更新UI }); }); ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值