完全解析Android多线程中线程池ThreadPool的原理和使用

前言对于多线程,大家应该很熟悉。但是,大家了解线程池吗?今天,我将带大家全部学习关于线程池的所有知识。

目录

1. 简介

2. 工作原理

2.1 核心参数线程池中有6个核心参数,具体如下

上述6个参数的配置 决定了 线程池的功能,具体设置时机 = 创建 线程池类对象时 传入

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种常用的线程池(即 已经配置好核心参数),下面会详细说明

2.2 内部原理逻辑

当线程池运行时,遵循以下工作逻辑

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. 常见的4类功能线程池

根据参数的不同配置,Java中最常见的线程池有4类:

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

即 对于上述4类线程池,Java已根据 应用场景 配置好核心参数

4.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();

4.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();

4.3 可缓存线程池(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();

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

4.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();

4.5 常见线程池 总结 & 对比

5. 总结阅读本文后,相信你已经非常了解线程池 & 用法接下来,我会继续讲解Android开发中关于多线程的知识,具体包括Thread类、Handler、HandlerThread等等,有兴趣可以继续关注Carson_Ho的安卓开发笔记请帮顶 / 评论点赞!因为你的鼓励是我写作的最大动力!

您可能感兴趣的文章:

  • python线程池threadpool使用篇
  • Spring线程池ThreadPoolTaskExecutor配置详情
  • python线程池(threadpool)模块使用笔记详解
  • C#多线程ThreadPool线程池详解
  • java ThreadPoolExecutor 并发调用实例详解
(0)

相关推荐

  • Spring线程池ThreadPoolTaskExecutor配置详情

    本文介绍了Spring线程池ThreadPoolTaskExecutor配置,分享给大家,具体如下: 1. ThreadPoolTaskExecutor配置 <!-- spring thread pool executor --> <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <!-- 线

  • C#多线程ThreadPool线程池详解

    简单说明一下: 线程池可以看做容纳线程的容器:一个应用程序最多只能有一个线程池:ThreadPool静态类通过QueueUserWorkItem()方法将工作函数排入线程池: 每排入一个工作函数,就相当于请求创建一个线程: 线程池的作用: 1.线程池是为突然大量爆发的线程设计的,通过有限的几个固定线程为大量的操作服务,减少了创建和销毁线程所需的时间,从而提高效率. 2.如果一个线程的时间非常长,就没必要用线程池了(不是不能作长时间操作,而是不宜.),况且我们还不能控制线程池中线程的开始.挂起.和

  • python线程池threadpool使用篇

    最近在做一个视频设备管理的项目,设备包括(摄像机,DVR,NVR等),包括设备信息补全,设备状态推送,设备流地址推送等,如果同时导入的设备数量较多,如果使用单线程进行设备检测,那么由于设备数量较多,会带来较大的延时,因此考虑多线程处理此问题. 可以使用python语言自己实现线程池,或者可以使用第三方包threadpool线程池包,本主题主要介绍threadpool的使用以及其里面的具体实现. 1.安装 使用安装: pip installthreadpool 2.使用 (1)引入threadpo

  • python线程池(threadpool)模块使用笔记详解

    最近在做一个视频设备管理的项目,设备包括(摄像机,DVR,NVR等),包括设备信息补全,设备状态推送,设备流地址推送等,如果同时导入的设备数量较多,如果使用单线程进行设备检测,那么由于设备数量较多,会带来较大的延时,因此考虑多线程处理此问题. 可以使用python语言自己实现线程池,或者可以使用第三方包threadpool线程池包,本主题主要介绍threadpool的使用以及其里面的具体实现. 一.安装与简介 pip install threadpool pool = ThreadPool(po

  • java ThreadPoolExecutor 并发调用实例详解

    java ThreadPoolExecutor 并发调用实例详解 概述 通常为了提供任务的处理速度,会使用一些并发模型,ThreadPoolExecutor中的invokeAll便是一种. 代码 package test.current; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.concurrent.Callable; import java.util

  • 完全解析Android多线程中线程池ThreadPool的原理和使用

    前言对于多线程,大家应该很熟悉.但是,大家了解线程池吗?今天,我将带大家全部学习关于线程池的所有知识. 目录 1. 简介 2. 工作原理 2.1 核心参数线程池中有6个核心参数,具体如下 上述6个参数的配置 决定了 线程池的功能,具体设置时机 = 创建 线程池类对象时 传入 ThreadPoolExecutor类 = 线程池的真正实现类 开发者可根据不同需求 配置核心参数,从而实现自定义线程池 // 创建线程池对象如下 // 通过 构造方法 配置核心参数 Executor executor =

  • C#多线程之线程池ThreadPool用法

    目录 一.ThreadPool 1.QueueUserWorkItem() 2.GetMaxThreads() 3.GetMinThreads() 4.SetMaxThreads()和SetMinThreads() 二.线程等待 三.线程重用 一.ThreadPool ThreadPool是.Net Framework 2.0版本中出现的. ThreadPool出现的背景:Thread功能繁多,而且对线程数量没有管控,对于线程的开辟和销毁要消耗大量的资源.每次new一个THread都要重新开辟内

  • C#多线程之线程池(ThreadPool)

    一.简介 前面介绍了平时用到的大多数的多线程的例子,但在实际开发中使用的线程往往是大量的和更为复杂的,这时,每次都创建线程.启动线程.从性能上来讲,这样做并不理想(因为每使用一个线程就要创建一个,需要占用系统开销):从操作上来讲,每次都要启动,比较麻烦.为此引入的线程池的概念. 好处: 1.减少在创建和销毁线程上所花的时间以及系统资源的开销 2.如不使用线程池,有可能造成系统创建大量线程而导致消耗完系统内存以及”过度切换”. 在什么情况下使用线程池? 1.单个任务处理的时间比较短 2.需要处理的

  • C#多线程之线程池ThreadPool详解

    一.ThreadPool概述 提供一个线程池,该线程池可用于执行任务.发送工作项.处理异步 I/O.代表其他线程等待以及处理计时器. 创建线程需要时间.如果有不同的小任务要完成,就可以事先创建许多线程/在应完成这些任务时发出请求.不需要自己创建这样一个列表.该列表由ThreadPool类托管. 这个类会在需要时增减池中线程的线程数,直到最大的线程数.池中的最大线程数是可配置的.在双核CPU中,默认设置为1023 个工作线程和1000个I/O线程.也可以指定在创建线程池时应立即启动的最小线程数,以

  • 深入解析C++编程中线程池的使用

    为什么需要线程池 目前的大多数网络服务器,包括Web服务器.Email服务器以及数据库服务器等都具有一个共同点,就是单位时间内必须处理数目巨大的连接请求,但处理时间却相对较短. 传 统多线程方案中我们采用的服务器模型则是一旦接受到请求之后,即创建一个新的线程,由该线程执行任务.任务执行完毕后,线程退出,这就是是"即时创建,即 时销毁"的策略.尽管与创建进程相比,创建线程的时间已经大大的缩短,但是如果提交给线程的任务是执行时间较短,而且执行次数极其频繁,那么服务器将处于 不停的创建线程,

  • Android开发中线程池源码解析

    线程池(英语:thread pool):一种线程使用模式.线程过多会带来调度开销,进而影响缓存局部性和整体性能.而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务.这避免了在处理短时间任务时创建与销毁线程的代价.线程池不仅能够保证内核的充分利用,还能防止过分调度.可用线程数量应该取决于可用的并发处理器.处理器内核.内存.网络sockets等的数量. 例如,线程数一般取cpu数量+2比较合适,线程数过多会导致额外的线程切换开销.----摘自维基百科 我们在Android或者Java开发中

  • java中多线程与线程池的基本使用方法

    目录 前言 继承Thread 实现Runnale接口 Callable 线程池 常见的4种线程池. 总结 前言 在java中,如果每个请求到达就创建一个新线程,开销是相当大的.在实际使用中,服务器在创建和销毁线程上花费的时间和消耗的系统资源都相当大,甚至可能要比在处理实际的用户请求的时间和资源要多的多.除了创建和销毁线程的开销之外,活动的线程也需要消耗系统资源.如果在一个jvm里创建太多的线程,可能会使系统由于过度消耗内存或"切换过度"而导致系统资源不足.为了防止资源不足,服务器应用程

  • java简单实现多线程及线程池实例详解

    本文为大家分享了java多线程的简单实现及线程池实例,供大家参考,具体内容如下 一.多线程的两种实现方式 1.继承Thread类的多线程 /** * 继承Thread类的多线程简单实现 */ public class extThread extends Thread { public void run(){ for(int i=0;i<100;i++){ System.out.println(getName()+"-"+i); } } public static void mai

  • 一文彻底搞懂java多线程和线程池

    目录 什么是线程 一. Java实现线程的三种方式 1.1.继承Thread类 1.2.实现Runnable接口,并覆写run方法 二. Callable接口 2.1 Callable接口 2.2 Future接口 2.3 Future实现类是FutureTask. 三. Java线程池 3.1.背景 3.2.作用 3.3.应用范围 四. Java 线程池框架Executor 4.1.类图: 4.2 核心类ThreadPoolExecutor: 4.3 ThreadPoolExecutor逻辑结

随机推荐