Android Thread Pool(线程池)

本文详细介绍了Java中线程池的使用方法及不同类型的线程池特性,包括Executor、ExecutorService、ScheduledExecutorService和ThreadPoolExecutor等接口和类的使用场景。

众所周知,显式创建,开启线程的方式:

             new Thread( new  RunnableTask() ).start();

这种方式,每次调用都会产生对象(java编程中产生对象,就要开辟内存空间)。当频繁调用线程时,这种方式开启线程会占很多的内存。

针对各种需求,优化内存,java 拥有更优雅的方式调用线程,即通过线程池来调用。

(一)Executor接口:

Executor是一个灵活的基于接口的任务执行工具,属于java.util.concurrent包中。

 ExecutorService executor= Executors.newSingleThreadExecutor() ;

  添加任务的方法:
       executor.execute(runnable); 

  终止的方法:
       shutdown():等待线程池中任务执行完后(期间不再接受新任务),再关闭 

(二)ExecutorService接口:

特性:

ExecutorService接口 是Executor接口的子接口

api: 
   submit():提交一个 Runnable 任务用于执行
   shutdown():等待线程池中任务执行完后(期间不再接受新任务),再关闭 
   shutdownNow():立刻关闭线程池,终止进行的任务,返回没有执行的任务    

产生方式:

  Executors一个线程池的工具类,里面含有静态工厂,产生不同需求的executor service,即针对不同需求的线程池 

1.适合小程序的线程池:

   ExecutorService pool = Executors.newCachedThreadPool();

    特性:线程池中线程可重用,若是没有可用线程,创建新的线程(适合小程序)

    缺点:添加的任务立马执行(若是没有缓存可用的线程,则创建新的线程),不存在任务队列,
           若是执行的任务太多,会导致cpu被占据(大负载的服务器不适用) 

2.适合大负载的服务器的线程池:

     ExecutorService pool = Executors.newFixedThreadPool(int nThreads) 

      特性: 可重用,线程数量固定的线程池,以共享的无界队列方式来运行这些线程
       (ps:若是更有效控制线程池,使用ThreadPoolExecutor)  

(三)ScheduledExecutorService接口:

特性:

ScheduledExecutorService:一个定时周期任务的线程(首次可以延迟),ExecutorService的子接口  

 api: 
 schedule():
            使用各种延迟创建任务,并返回一个可用于取消或检查执行的任务对象 
 scheduleAtFixedRate() 和 scheduleWithFixedDelay() :
             创建并执行某些在取消前一直定期运行的任务。 

好处:

用于替代java.utls.Timer 
     Timer+thread模式的缺点:
               1.只能调用一个线程执行任务,对于周期性的任务,会导致定时不准确
               2.当timer所对应的thread抛出异常时,线程停止。

  ScheduledExecutorService的好处:支持多线程,从抛出异常的任务中恢复  

使用方式:

     // 定时任务    
     private ScheduledExecutorService scheduledExecutorService; 

                 scheduledExecutorService =   
                           //产生方式1:
                           Executors.newSingleThreadScheduledExecutor(); 

                          //产生方式2:   
                           Executors. newScheduledThreadPool(1); 


        //开启线程方式:
        scheduleAtFixedRate(Runnable command, long initialDelay,long period,TimeUnit unit)
        //参数:执行的Runnable对象,首次延迟时间,周期(即每隔多久执行一次,时间单位)
使用场景:定时任务,如广告轮播图等 

(四)ThreadPoolExecutor类:

特性:

ThreadPoolExecutor是一个ExecutorService的实现类,这个类允许你控制线程池操作的几乎每一个方面(推举使用) 

使用方式:

 ThreadPoolExecutor threadPool=ThreadPoolExecutor(int corePoolSize,  
                                   int maximumPoolSize,  
                                   long keepAliveTime,   
                                   TimeUnit unit,
                                   BlockingQueue workQueue, 
                                   RejectedExecutionHandler handler)

          //参数:
             corePoolSize:  线程池维护线程的最少数量
             maximumPoolSize:线程池维护线程的最大数量
             keepAliveTime: 线程池维护线程所允许的空闲时间
             unit: 线程池维护线程所允许的空闲时间的单位
             workQueue: 线程池所使用的缓冲队列
             handler: 线程池对拒绝任务的处理策略     

         //执行runnable 对象:
           threadPool.execute(runnable);

运用场景:android 加载图片的线程池 或者 普通功能的线程池 或者 联网功能的线程池

android官方案例:通过线程池加载图片(只涉及线程池配置)

 // 获取cpu中允许的最大线程数
    private static final int POOLSIZE = Runtime.getRuntime()
            .availableProcessors();

    private static final int keepAliveTime = 1;
    private static final TimeUnit unit = TimeUnit.SECONDS;
    private final BlockingQueue<Runnable> queue;
    private final ThreadPoolExecutor threadPool;

        queue = new LinkedBlockingQueue<Runnable>();
        //配置线程池
        threadPool = new ThreadPoolExecutor(POOLSIZE, 
                             POOLSIZE, 
                             keepAliveTime,
                             unit,  
                             queue);

实际项目线程池使用,参考::android 高效加载bitmap

衍生点:

1.虽然官方封装了一个含有线程池+handler回调异步加载工具AsyncTask, 但是工作任务队列限制为128个,对于部分需求不能满足

2.android 更新UI : Handler+ExecutorService(线程池)+MessageQueue+缓存模式(针对AsyncTask的解决方式,推举使用)

3.对AsyncTask感兴趣的,可以阅读 AsyncTask介绍

<think>嗯,用户想了解Android线程池的使用方法和实现方式。首先,我需要回忆一下线程池的基本概念,然后结合Android的具体实现来组织回答。根据提供的引用资料,Android中的线程池主要基于Java的Executor框架,具体实现是ThreadPoolExecutor。用户可能需要知道如何创建线程池,不同类型的线程池,以及它们的适用场景。 首先,引用[4]提到ThreadPoolExecutor提供了一系列参数来配置线程池,不同的参数可以创建不同类型的线程池。所以需要解释ThreadPoolExecutor的构造参数,比如核心线程数、最大线程数、存活时间、工作队列等。然后,引用[1]和[2]指出Android提供了Executors工厂类来创建常见的线程池,比如FixedThreadPool、CachedThreadPool等,这些可能更方便开发者使用。 接下来,用户可能需要具体的代码示例。引用[3]展示了一个使用ThreadPoolExecutor.execute()提交任务的例子,可以引用这个来说明基本用法。另外,需要说明如何通过Executors创建不同类型的线程池,比如Executors.newFixedThreadPool(),并解释每种类型的特性和适用场景,比如FixedThreadPool适合执行长期任务,CachedThreadPool适合短期异步任务等。 关于实现原理,引用[5]提到线程的创建是通过ThreadFactory接口,默认使用Executors.defaultThreadFactory(),但也可以自定义。这部分需要简要说明线程池如何管理线程的生命周期,任务队列的处理策略,比如当核心线程满后,任务进入队列,队列满后再创建新线程,直到达到最大线程数,之后可能会触发拒绝策略。 此外,需要注意用户可能的问题,比如如何选择线程池类型,如何避免内存泄漏,或者性能优化的方法。根据引用[1]中的最佳实践,比如避免使用无界队列,合理设置线程数,使用自定义ThreadPoolExecutor进行更精细的控制等。 最后,生成相关问题需要考虑用户可能进一步想知道的内容,比如线程池参数配置、不同线程池的对比、异常处理机制,或者如何监控线程池状态等。</think>### Android线程池使用与实现详解 #### 一、线程池基础概念 Android线程池基于Java的$Executor$框架实现,核心实现类为$ThreadPoolExecutor$。它能有效管理线程生命周期,避免频繁创建/销毁线程的性能损耗[^4]。其核心参数包括: - **核心线程数**:长期保留的线程数量 - **最大线程数**:允许创建的最大线程数量 - **存活时间**:非核心线程空闲存活时间 - **任务队列**:存放待执行任务的阻塞队列 #### 二、标准线程池类型 通过$Executors$工厂类可快速创建四种常用线程池: 1. **FixedThreadPool** ```java ExecutorService fixedPool = Executors.newFixedThreadPool(4); // 固定4个线程 ``` 特点:线程数量固定,适合长期任务处理[^2] 2. **CachedThreadPool** ```java ExecutorService cachedPool = Executors.newCachedThreadPool(); ``` 特点:自动扩展/回收线程,适合短期异步任务[^2] 3. **ScheduledThreadPool** ```java ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(3); scheduledPool.schedule(task, 5, TimeUnit.SECONDS); // 延迟执行 ``` 特点:支持定时/周期性任务[^2] 4. **SingleThreadExecutor** ```java ExecutorService singlePool = Executors.newSingleThreadExecutor(); ``` 特点:保证任务顺序执行[^2] #### 三、自定义线程池实现 通过$ThreadPoolExecutor$构造函数可精细化控制: ```java ThreadPoolExecutor customPool = new ThreadPoolExecutor( 2, // 核心线程数 5, // 最大线程数 60L, TimeUnit.SECONDS, // 空闲线程存活时间 new LinkedBlockingQueue<>(10), // 任务队列容量 Executors.defaultThreadFactory(), // 线程工厂 new ThreadPoolExecutor.AbortPolicy() // 拒绝策略 ); ``` 参数配置示例说明: $$线程池容量 = 核心线程 + 队列容量 + (最大线程 - 核心线程)$$ #### 四、最佳实践 1. **任务提交方式** ```java // 使用execute()提交Runnable任务 threadPoolExecutor.execute(new Runnable() { @Override public void run() { // 任务逻辑代码 } }); // 使用submit()提交Callable任务 Future<String> future = threadPoolExecutor.submit(new Callable<String>() { @Override public String call() throws Exception { return "task result"; } }); ``` 2. **注意事项** - 避免使用无界队列(可能导致OOM) - 根据CPU核心数设置合理线程数(通常核心数+1) - 及时调用shutdown()释放资源 - 使用自定义$RejectedExecutionHandler$处理任务拒绝 #### 五、实现原理 1. **线程管理机制** - 任务优先进入核心线程 - 队列满后创建非核心线程 - 达到最大线程数后触发拒绝策略[^4] 2. **核心执行流程** ```mermaid graph TD A[提交任务] --> B{核心线程是否空闲?} B -->|是| C[立即执行] B -->|否| D{队列是否已满?} D -->|否| E[加入等待队列] D -->|是| F{是否达到最大线程数?} F -->|否| G[创建新线程执行] F -->|是| H[执行拒绝策略] ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值