Android基础 -- Android线程池的使用

本文介绍了Android线程池的概念,强调其降低性能开销、提高响应速度的优势。线程池有核心线程数、最大线程数、存活时间等核心参数。详细解释了线程池的工作原理,包括任务分配的优先级。还列举了五种常见的线程池类型,如FixedThreadPool用于控制并发,ScheduledThreadPool用于定时任务,CachedThreadPool用于灵活回收线程,SingleThreadExecutor保证任务顺序执行,而WorkStealingPool适合处理耗时任务。

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

小伙伴们对于Thread、Runnable、Handler、AyscTask应该十分熟悉,并且借助它们完成了一个个炫酷的功能,那么关于线程池的了解呢?这边文章就和小伙伴一起来看看关于线程池的这些事

1.什么是线程池

线程池是1块缓存了一定线程数量的区域,用来复用线程和管理线程,如统一分配、调优、监控和控制最大并发数等

优点:

  • 降低因线程创建销毁所带来的性能开销 重用缓存线程池的线程
  • 提高线程响应速度和执行效率 通过重用线程 不需要创建线程即可马上执行 优化线程的执行顺序 避免大量线程因互相抢占系统资源而导致的阻塞现象

2.工作原理

线程中有6个核心参数

  • corePoolSize : 核心线程数 ,默认情况下,核心线程会一直存活(包括空闲状态)
  • maximumPoolSize:线程池所能容纳的最大线程数,当活动线程数达到该数值后,后续新的任务将会阻塞
  • keepAliveTime:非核心线程 限制超时时长,超过该时长,非核心线程就会被回收
  • unit:指定 keepAliveTime参数的时间单位,毫秒、秒等
  • workQueue:任务队列,通过线程池的execute方法提交的Runnable对象,将存储在该参数中
  • threadFactory:线程工厂(接口)用来为线程池创建新的线程 Thread newThread(Runnable r)

ThreadPoolExecutor是线程池的真正实现类

// 创建线程池对象如下
// 通过 构造方法 配置核心参数
   Executor executor = new ThreadPoolExecutor( 
                                              CORE_POOL_SIZE,
                                              MAXIMUM_POOL_SIZE,
                                              KEEP_ALIVE,
                                              TimeUnit.SECONDS, 
                                              sPoolWorkQueue,
                                              sThreadFactory 
                                               );

// 构造函数源码分析
    public ThreadPoolExecutor (int corePoolSize,
                               int maximumPoolSize,
                               long keepAliveTime,
                               TimeUnit unit,
                               BlockingQueue<Runnable workQueue>,
                               ThreadFactory threadFactory )

 Java里内置了4中常用的线程池(即配置好核心参数的线程池)

处理任务的优先级:核心线程 > 任务队列 > 最大线程

当一个任务需要线程池去执行的时候,首先

判断线程池中的线程数是否大于核心线程数,如果小于,就在核心线程里创建一个线程执行任务

如果大于

判断任务队列是否已满,如果没有满,任务被放到任务队列(等待执行)

如果满了

判断线程池中的线程数是否大于最大线程数,如果小于,就在非核心线程里创建一个线程执行任务

如果大于

表示该任务无法执行 通过handler指定的策略处理任务

 

特别说明:当线程池中的线程数量 > 核心线程数时,若某非核心线程的空闲时间大于keepAliveTime,线程将被终止,通过这样的策略,线程池可以动态的调整线程中的线程数

 

3.使用流程

// 1. 创建线程池
   // 创建时,通过配置线程池的参数,从而实现自己所需的线程池
   Executor threadPool = new ThreadPoolExecutor(
                                              CORE_POOL_SIZE,
                                              MAXIMUM_POOL_SIZE,
                                              KEEP_ALIVE,
                                              TimeUnit.SECONDS,
                                              sPoolWorkQueue,
                                              sThreadFactory
                                              );
    // 注:在Java中,已内置4种常见线程池,下面会详细说明

// 2. 向线程池提交任务:execute()
    // 说明:传入 Runnable对象
       threadPool.execute(new Runnable() {
            @Override
            public void run() {
                ... // 线程执行任务
            }
        });

// 3. 关闭线程池shutdown() 
  threadPool.shutdown();
  
  // 关闭线程的原理
  // a. 遍历线程池中的所有工作线程
  // b. 逐个调用线程的interrupt()中断线程(注:无法响应中断的任务可能永远无法终止)

  // 也可调用shutdownNow()关闭线程:threadPool.shutdownNow()
  // 二者区别:
  // shutdown:设置 线程池的状态 为 SHUTDOWN,然后中断所有没有正在执行任务的线程
  // shutdownNow:设置 线程池的状态 为 STOP,然后尝试停止所有的正在执行或暂停任务的线程,并返回等待执行任务的列表
  // 使用建议:一般调用shutdown()关闭线程池;若任务不一定要执行完,则调用shutdownNow()

4.常见的5种线程池

  • 定长线程池(FixedThreadPool)
  • 定时线程池(ScheduledThreadPool )
  • 可缓存线程池(CachedThreadPool)
  • 单线程化线程池(SingleThreadExecutor)
  • 耗时任务线程池(WorkStealingPool)

1) 定长线程池(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();

2)定时线程池(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();

3)可缓存线程池(CachedTheadPool)

特点:只有非核心线程、线程数量不固定(可无限大)、灵活回收空闲线程(具备超时机制,全部回收时几乎不占系统资源)、新建线程(无线程可用时)

任何线程任务到来都会立刻执行,不需要等待

应用场景:执行大量、耗时少的线程任务

使用:通过Executors.newCachedTheadPool()创建

// 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();

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

 4)单线程化线程池(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();

5)耗时任务线程池(WorkStealingPool)

WorkStealingPool适合使用在很耗时的操作,但是WorkStealingPool不是ThreadPoolExecutor的扩展,它是新的线程池类ForkJoinPool的扩展,但是都是在统一的一个Executors类中实现,由于能够合理的使用CPU进行对任务操作(并行操作),所以适合使用在很耗时的任务中

// 1. 创建单线程化线程池
        ExecutorService workStealingPool = Executors.newWorkStealingPool();

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

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

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值