一、概念讲解

进程:是程序运行过程中系统进行资源分配和调度的一个独立单位,使多个程序可 并发执行,以提高系统的资源利用率和吞吐量。

线程:一个基本的CPU执行单元 & 程序执行流的最小单元。 线程自己不拥有系统资源,与其他线程共享进程所拥有的全部资源。(并发、同步)

线程和进程的关系:进程是资源分配的最小单位,线程是CPU调度的最小单位。 线程依附于进程。

二、线程的分类

UI线程(主线程):Android系统在程序启动时会自动启动一条主线程 处理四大组件与用户进行交互的事情(如 UI 显示、界面交互相关)。

工作线程(子线程):手动创建的线程,主要用于耗时的操作(网络请求、I/O 操作等) 。

三、线程优先级

Android 系统中线程线程优先级分为10个级别,分别用Thread类常量表示。

设置线程优先级:通过方法 setPriority(int grade) 进行优先级设置,默认线程优先级是5,即 Thread.NORM_PRIORITY。

四、线程的生命周期

线程的生命周期:新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Dead)五种状态

1\

五、Android多线程实现方式

1、基础实现方式

1、继承 Thread 类,重写 run() 方法;

2、实现 Runnable 接口,重写 run() 方法

3、实现 Callable 接口,重写 call() 方法

2、组件实现方式

1、AsyncTask

是一个 Android 已封装好的轻量级异步类,属于抽象类,即使用时需实现子类。在工作线程中执行任务,如耗时任务 可以将工作线程的执行结果传递给主线。

2、HandlerThread

是一个 Android 已封装好的轻量级异步类。在工作线程中执行任务,如耗时任务 可以将工作线程的执行结果传递给主线。可实现延迟操作。

3、IntentService

是Android 里的一个封装类,继承四大组件之一的 Service。处理异步请求 & 实现多线程 不符合多个数据同时请求的场景。所有的任务都在同一个 Thread looper 里执行。

3、高级实现形式 -- 线程池(ThreadPool)

可复用并管理线程,如控制最大并发线程数量、统一分配 & 调度。降低因线程的创建 & 销毁带来的性能开销。提高线程响应速度 & 执行效率。

 构造函数:

常见的4种功能线程池

1、定长线程池(FixedThreadPool)。只有核心线程 & 不会被回收、线程数量固定、任务队列无大小限制(超出的线程任务会在队列中等待) ,控制线程最大并发数,通过 Executors.newFixedThreadPool() 创建

2、定时线程池(ScheduledThreadPool )核心线程数量固定、非核心线程数量无限制(闲置时马上回收),执行定时 / 周期性 任务,通过 Executors.newScheduledThreadPool()创建

3、可缓存线程池(CachedThreadPool)只有非核心线程、线程数量不固定(可无限大)、灵活回收空闲线程(具备超时机制,全部回收时几乎不占系统资源)、新建线程(无线程可用时), 执行大量、耗时少的线程任务,通过 Executors.newCachedThreadPool()创建

4、单线程化线程池(SingleThreadExecutor)只有一个核心线程(保证所有任务按照指定顺序在一个线程中执行,不需要处理线程同步的问题),不适合并发但可能引起IO阻塞性及影响UI线程响应的操作,如数据库操作,文件操作等,通过 Executors.newSingleThreadExecutor()创建

六、线程安全

线程安全需要保证基本特性:

  • 原子性:简单说就是相关操作不会被其他线程干扰,一般通过同步机制实现
  • 可见性:一个线程修改了某个共享变量,其状态能够立即被其他线程知晓
  • 有序性:保证线程内串行语义,避免指令重排等

1、Synchronized 关键字

  1. sychronized 是 java 中的内置锁,可以限制线程对代码块或者方法的访问 Sychronized 可以修饰类方法,实例方法,代码块
  2. 在执行 sychronized 方法或代码块时,线程需要先获取被修饰对象的锁。一次只能有一个线程可以获取到一个对象的锁,同一个线程可以多次获取同一个对象的锁(可重入锁)
  3. sychronized 不能响应中断,当一个线程在等待锁的时候,调用该线程的 interrupt 是不起作用的
  4. 锁的获取和释放是隐式的,进入同步 sychronized blocks 后会获取锁,离开 sychronized blocks 后会释放锁

2、Obejct类的wait/notify方法

  1. wait/notify 是用于线程同步的方法。
  2. wait 方法会使得当前线程放弃调用对象的监控,并使当前线程进入等待。直到调用了该对象的 notify 方法或者 notifyAll 方法(语法上是这样设计,但存在例外)
  3. 可以多次调用对象的wait方法,notify 方法只会随机释放一个wait方法等待,与调用顺序无关。如果要释放所有的 wait 调用可以调用 notifyAll 方法。
  4. 调用 wait 的线程有可能会存在 interrupt,虚假唤醒的情况,导致 wait 方法返回,但实际并没有调用对象的 notify 方法。在使用时通常会搭配一个 lock flag 和 loop 使用。

3、重入锁实现线程同步 Lock

1、一般使用其实现类 ReentrantLock,ReentrantLock获取锁定与三种方式:

  1. lock():如果获取了锁立即返回,如果别的线程持有锁,当前线程则一直处于休眠状态,直到获取锁
  2. tryLock():如果获取了锁立即返回 true,如果别的线程正持有锁,立即返回 false;
  3. tryLock(long timeout,TimeUnit unit):如果获取了锁定立即返回 true,如果别的线程正持有锁,会等待参数给定的时间,在等待的过程中,如果获取了锁定,就返回 true,如果等待超时,返回 false;
  4. lockInterruptibly:如果获取了锁定立即返回,如果没有获取锁定,当前线程处于休眠状态,直到或者锁定,或者当前线程被别的线程中断

2、ReentrantLock 和 Synchronized 的区别:

线程 A 和 B 都要获取对象 O 的锁定,假设 A 获取了对象 O 锁,B 将等待 A 释放对 O 的锁定:

  1. 如果使用 synchronized ,如果 A 不释放,B 将一直等下去,不能被中断
  2. 如果 使用 ReentrantLock ,如果 A 不释放,可以使 B 在等待了足够长的时间以后,中断等待,而干别的事情

七、经验总结

1、禁止在代码中使用“new Thread”创建新的 Thread !

  • 浪费线程资源
  • 无法控制该线程的执行,因此可能会造成不必要的内存泄漏

2、禁止频繁使用 HandlerThread !

  • HandlerThread 继承于 Thread 类,所以每次开启一个 HandlerThread 就和开启个普通 Thread 一样,很浪费资源
  • 只适用于解决此类需求 -“要在指定的一个线程下执行某些任务”

3、禁止直接使用 AsyncTask.execute() 执行耗时操作!

  • Execute 直接访问了 Executor,这样使用完全丧失了 AsyncTask 本身的意图
  • 可能会造成不必要的内存泄漏

4、严禁使用 Executors 工具类来创建线程池

  • 尤其是 newFixedThreadPool 和 newCachedThreadPool 这两个方法
  • 当核心线程执行时间很长(比如 sleep10s),则新提交的任务还在不断地插入到阻塞队列中,最终造成 OOM
  • 当核心线程耗时很久,线程池会尝试创建新的线程来执行提交的任务,当内存不足时就会报无法创建线程的错误

这只是个人对于Android中线程的总结,如果有错误,欢迎大家留言!

Android 中的多线程简介相关推荐

  1. Android中的多线程(字节跳动)

    文章目录 Handler机制(Android中的消息队列机制) Handler机制为Android系统解决了以下两个问题 Handler常用方法 Handler的使用 补充知识点 Handler原理 ...

  2. Android中的多线程编程与异步处理

    Android中的多线程编程与异步处理 引言 在移动应用开发中,用户体验是至关重要的.一个流畅.高效的应用能够吸引用户并提升用户满意度.然而,移动应用面临着处理复杂业务逻辑.响应用户输入.处理网络请求 ...

  3. android build.ninja,Android中的Ninja简介

    Android中的Ninja简介 2017-08-15 16:49:42 +08 字数:2671 标签: Android Makefile Ninja 如果说Makefile是一个DSL,那么Ninj ...

  4. Android中的多线程

    文章目录 多线程 多线程的引入 模拟耗时任务 什么是主线程 什么是子线程 使用Handler处理多线程 Handler Handler的使用步骤 例子一 模拟进度条的加载 使用AsyncTask处理多 ...

  5. 在Android中使用FlatBuffers - 简介

    JSON - 可能每个人都知道这个轻量的数据格式几乎被用在了所有的现代服务器中.相对于过去流行的一些东西,如可怕的XML,它更轻量,更可读,对开发更友好.JSON是语言独立的数据格式,但解析和格式转化 ...

  6. (Android小应用)在Android中实现多线程断点下载(连载二)

    前面已经讲了通过多线程下载网络文件的一部分核心代码,下面继续做我们的项目 当然如果我们做小一点的Android项目的时候可以先做界面,然后根据需要来扩展所需要的功能,当然有的时候我们宁愿先实现业务,业 ...

  7. android 蓝牙相关的类,Android中BluetoothAdapter类简介

    一. BluetoothAdapter类介绍 BluetoothAdapter类简单点来说就是代表了本设备(手机.电脑等)的蓝牙适配器对象,通过它我们可以蓝牙设备进行基本 开发了,主要有如下功能: 1 ...

  8. C语言中的多线程简介

    线程 Thread 专业术语称之为程序执行流的最小单元 .线程是不会执行程序的,可以理解成线程就是一个载体,将 要执行的代码 运送到CPU进行处理. 多线程就是多个线程同时并发执行. (注意并发与并行 ...

  9. Android中的StrictMode简介

    .build()); 当然,以上代码只应在未发布上线的测试版本的应用中运行以方便监视相关的运行情况,当在生产版本上时不应该启用strictmode.因此,最佳的代码实践应该为如下的样子: public ...

最新文章

  1. Nature:AI 引导人类直觉,帮助发现数学定理
  2. 关于java中普通代码块、构造代码块与静态代码块
  3. 【c++】23.【函数指针】定义? 为什么不直接调用函数而要使用函数指针?
  4. 深入Dapper.NET源码
  5. 我们应该学习什么 java、C#还是C++(VC)
  6. 【nodejs原理源码赏析(6)】深度剖析cluster模块源码与node.js多进程
  7. sharepoint2013列表实现项目级权限控制
  8. 设计模式(三) 工厂模式
  9. spring5.0学习笔记10
  10. ECharts 教程
  11. 论文写作--学习所得
  12. Windows中的工作组(Work Group)、域(Domain)、域控(DC)、活动目录(AD)介绍
  13. 计算机老师为什么不用伽卡他卡做文件服务器?
  14. android 的语言适配
  15. 微信小程序-定时刷新发送请求
  16. 三十六 我在软件园的那些日子里
  17. 东北大学计算机难度,东北大学考研难吗
  18. python scrapy 管道学习,并拿在行练手爬虫项目
  19. 论文浅尝 | DI刊发的那些有关Knowledge Graph的论文
  20. 超级实习生内推的实习offer,实习经历企业认可吗?

热门文章

  1. 前端学习辑录(2):JS中this指向的问题
  2. 九星连珠用c语言编程,王者模拟战27号更新:九星连珠不再是梦想 贪婪天赋荣升A级...
  3. 微信小程序vue+uniapp高校食堂订餐就餐系统java+python+nodejs
  4. Flash WebGame 开发经验心得和PureMVC框架细说(2011-06-29 21:00:52)
  5. Domino系统组织名称、域名迁移
  6. 【Linux】之Jumpserver堡垒机添加Windows主机资产
  7. 高效轻量级深度模型的研究与实践
  8. [生存志] 第70节 孙子兵法十三篇
  9. 从零开始基于nonebot2搭建Q群机器人自动获取各大平台热搜
  10. 控制柜散热风扇的选型计算