Android ThreadPool 常见线程池

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zcpvn/article/details/81320692


程序启动一个新线程成本是比较高的,因为它涉及到要与操作系统进行交互。而使用线程池可以很好的提高性能,尤其是当程序中要创建大量生存期很短的线程时,更应该考虑使用线程池。线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象来使用。在JDK5之前,我们必须手动实现自己的线程池,从JDK5开始,Java内置支持线程池。

传统的多线程缺点:

  • 每次新建/销毁线程对象消耗资源、响应速度慢。
  • 线程缺乏统一管理,容易出现阻塞的情况。

使用线程池的好处:

  • 降低线程的创建和销毁带来的性能开销。
  • 控制线程并发数,合理使用系统资源,优化响应速度。
  • 提高对线程的管理度,如定时执行。

常见的4类线程池

Executor继承实现层次图

Android中的线程池用的是Java的线程池。
如图,Executor是一个接口,线程池的真正实现者是:ThreadPoolExecutor

我们一般不直接用ThreadPoolExecutor而是用如下4类:

  • 定长线程池(FixedThreadPool
  • 定时线程池(ScheduledThreadPool
  • 可缓存线程池(CachedThreadPool
  • 单线程化线程池(SingleThreadExecutor

对于上述4类线程池,Java已根据应用场景配置好了ThreadPoolExecutor的核心参数,用于实现不同特性的线程池。
开发者也可根据不同需求配置ThreadPoolExecutor的核心参数,从而实现自定义线程池。
关于ThreadPoolExecutor更详细的知识请移步 :Carson_Ho 还有 _江南一点雨


定长线程池(FixedThreadPool)

  • 特点:只有核心线程 & 不会被回收、线程数量固定、任务队列无大小限制(超出的线程任务会在队列中等待)
  • 应用场景:控制线程最大并发数
    具体使用:通过 Executors.newFixedThreadPool() 创建
    示例:
// 1. 创建定长线程池对象 & 设置线程池线程数量固定为3
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);

// 2. 创建好Runnable类线程对象 & 需执行的任务
Runnable task =new Runnable(){
  public void run(){
    System.out.println("执行任务啦");
     }
    };

// 3. 向线程池提交任务:execute()
fixedThreadPool.execute(task);

// 4. 关闭线程池
fixedThreadPool.shutdown();

定时线程池(ScheduledThreadPool )

  • 特点:核心线程数量固定、非核心线程数量无限制(闲置时马上回收)
  • 应用场景:执行定时 / 周期性 任务
    使用:通过 Executors.newScheduledThreadPool() 创建
    示例:
// 1. 创建 定时线程池对象 & 设置线程池线程数量固定为5
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);

// 2. 创建好Runnable类线程对象 & 需执行的任务
Runnable task =new Runnable(){
       public void run(){
              System.out.println("执行任务啦");
          }
    };
// 3. 向线程池提交任务:schedule()
scheduledThreadPool.schedule(task, 1, TimeUnit.SECONDS); // 延迟1s后执行任务
scheduledThreadPool.scheduleAtFixedRate(task,10,1000,TimeUnit.MILLISECONDS);// 延迟10ms后、每隔1000ms执行任务

// 4. 关闭线程池
scheduledThreadPool.shutdown();

可缓存线程池(CachedThreadPool)

  • 特点:只有非核心线程、线程数量不固定(可无限大)、灵活回收空闲线程(具备超时机制,全部回收时几乎不占系统资源)、新建线程(无线程可用时)
  • 任何线程任务到来都会立刻执行,不需要等待
  • 应用场景:执行大量、耗时少的线程任务
    使用:通过 Executors.newCachedThreadPool() 创建
    示例:
// 1. 创建可缓存线程池对象
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();

// 2. 创建好Runnable类线程对象 & 需执行的任务
Runnable task =new Runnable(){
  public void run(){
        System.out.println("执行任务啦");
            }
    };

// 3. 向线程池提交任务:execute()
cachedThreadPool.execute(task);

// 4. 关闭线程池
cachedThreadPool.shutdown();

//当执行第二个任务时第一个任务已经完成
//那么会复用执行第一个任务的线程,而不用每次新建线程。

单线程化线程池(SingleThreadExecutor)

  • 特点:只有一个核心线程(保证所有任务按照指定顺序在一个线程中执行,不需要处理线程同步的问题)。
  • 应用场景:不适合并发但可能引起IO阻塞性及影响UI线程响应的操作,如数据库操作,文件操作等。
    使用:通过 Executors.newSingleThreadExecutor() 创建。
    示例:
// 1. 创建单线程化线程池
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

// 2. 创建好Runnable类线程对象 & 需执行的任务
Runnable task =new Runnable(){
    public void run(){
        System.out.println("执行任务啦");
    }
};

// 3. 向线程池提交任务:execute()
singleThreadExecutor.execute(task);

// 4. 关闭线程池
singleThreadExecutor.shutdown();

本文参考并整理自:
Android 多线程: 完全解析线程池ThreadPool原理&使用
Android开发之线程池使用总结

猜你喜欢

转载自blog.csdn.net/zcpvn/article/details/81320692