07 |「异步任务」

前言

实践是最好的学习方式,技术也如此。

一、软件与操作系统

  • 软件

    • 定义: 软件是程序的载体,写的代码,打包出来就是软件,就能安装在各种设备上,然后运行在操作系统上。(程序就是用于指导计算机的一系列抽象指令,而软件是程序实际编译运行在计算机上而存在的产品。软件是程序的一种载体和实现形式。两者关系就像设计和产品、理论和实践)
    • 分类:系统软件(操作系统),应用软件(都要运行在操作系统上);
  • 操作系统

    • 作用
      • 1)负责跟系统硬件打交道,把用户的各种操作(比如鼠标点击、键盘输入等)翻译给计算机硬件,然后将结果告诉用户;
      • 2)管理其他软件;
    • 管理其他软件
      • 操作系统如何管理其它软件:通过管理进程;

二、进程与线程

  • 软件是程序的载体,每个程序都是一个进程;

  • 每个程序都有一个进程,线程是进程的一部分,线程是操作系统能调度的最小单元;

  • 通俗例子解释

    • 背景:村庄
      • 村长:操作系统; 管理每个家庭;单独指挥一个人去做事(一个线程);
      • 一个软件就是一个家庭,这个家庭就是一个进程;
      • 一个家庭是一个进程,家中有我、父亲、母亲(每个人都是一个线程);
  • 线程的优点

    • 使用线程可以提高程序的运行速度,节省时间和成本;
    • 变串行为并行,提高速度,节省时间;
      • 串行:一件事同一时刻只有一个人做;
      • 并行:一件事同一时刻有多个人做;
  • 多线程资源冲突:多个线程在同一时刻操作同一个资源;

    • 操作资源:对资源进行了修改;
      	// 定义资源i
      	int i = 10;
      	// 访问资源,没有修改i
      	println(i);
      	// 操作资源,对i进行了修改
      	i = 1;
      
  • 线程是进程的一部分,是操作系统调度的最小单位(是调度的最小单位,不是持有资源的最小单位);

  • 资源都是在进程中的,进程是持有资源的最小单位;线程可以使用资源,但是不能持有资源;

  • 每一个进程都有一块内存,这个内存是所有线程共享的。每一个线程都有一个缓存,这个缓存是自己独占的;

  • 例如,进程 p,进程 p 有个线程 a,线程 a 的执行逻辑

    • CPU 将 a 需要的数据从进程 P 的内存读入线程 a 的缓存;如 i;
    • a 对自己缓存的数据进行操作;如 i ++;
    • a 执行完毕,cpu 将 a 缓存的数据 i 写回到进程 p 的内存中;
  • 资源冲突:多个线程在同一时刻操作同一个资源;同一时刻,同一目标;
    线程 a 执行的同时,进程 p 中 的另一个线程 b 也在执行,且也用到了 P 内存中的 i;那么,线程 b 执行完成后,i 是多少呢,是以线程 a 执行的为准,还是线程 b 执行的为准;

  • 解决资源冲突:不同时或不同目标(破坏同一时间或同一目标这两个条件)

    • 不同时:排队,变并行为串行;在 i 被读入线程 a 的内存中时,加个标记;其它线程来看到这个标记会等着,等到线程 a 执行完成将 i 写回到内存中时,再把标记清除我,并通知其他线程,其他线程再开始执行。

1、进程

  • 进程(Process)是操作系统分配资源的基本单位,它是一个执行中的程序实例;
  • 每个进程都有自己独立的内存空间,不同进程的内存是相互独立的;
  • 在Android系统中,每个应用都会以一个新的进程运行,系统会自动帮我们管理这些进程;
  • 默认情况下,Android系统会为每个App分配一个进程。这个默认进程里可以包含多个Activity);
  • 当在这个进程内启动一个新的Activity时,是直接在该进程create一个Activity实例,不会创建新进程;
  • 多个Activity会共享该应用进程的资源和内存空间;
  • 单纯启动新Activity并不会造成进程切换,对系统资源影响较小

2、线程

* 线程就是让==一个程序==有能力==同时完成多件事情==;
  • 线程是正在运行的程序中的一条独立的执行路径;
  • 主线程
    • 当 Android 程序启动时,系统会创建一个主线程,也称为 UI 线程;
    • UI 线程是应用程序与 Android UI 工具包中的组件交互的方式(在这个线程中可以更新UI,处理用户输入事件等。UI组件像Activity、View都是在UI线程中初始化和创建的。);
    • UI线程负责处理用户界面的创建、更新和响应用户交互事件,确保应用的用户界面保持流畅、响应迅速,并提供良好的用户体验
    • UI 线程只能处理和界面相关的工作,比如绘制界面,处理点击事件等,区分UI线程和工作线程,就是让耗时操作不阻塞界面,以保证应用的流畅性和用户体验;
  • 后台(工作)线程是除主线程或 UI 线程之外的任何线程;
  • AsyncTask:
    • 来简化这种需要后台工作的场景;
    • 可以把AsyncTask看成一个工人,我们在主线程中告诉它需要做什么工作,它会自己另开一个线程(后台线程)去工作。工作完成后它再回到主线程,通过回调方法将结果返回给我们。这样下来,我们的主线程(UI线程)就可以专注于更新界面,不会被阻塞。而AsyncTask也封装了线程管理和线程间通信的复杂性,我们只需要告诉它做什么工作就可以了;
    • AsyncTask 通过异步线程可以避免阻塞,回调机制又可以获取结果;

三、实现

  • 回调:至于回调的概念,它表示一种函数或方法,当特定事件发生时就会被执行。回调不会主动调用,而是在满足条件时由别处调用以完成响应。在Android中,回调机制很常见,例如点击事件的onClick()就是一个回调方法。

AsyncTask通过线程间的回调,很好地结合了后台工作与UI更新,极大地方便了程序逻辑的管理。

  • TextView、Button;
  • 用户单击 Button 时,应用程序会休眠一段随机时间,然后在唤醒时在 TextView 中显示一条消息;
// 第一个泛型参数String: 表示异步任务输入参数的类型:String
// 第二个泛型参数Integer: 表示后台任务执行进度的类型:Integer
// 第三个泛型参数Bitmap: 表示异步任务最终返回结果的类型:

// 知识点:<T>表示类型参数T,用于在定义Box类时传入实际的类型
public class MyAsyncTask 
   extends AsyncTask <String, Integer, Bitmap>{}

应用现在有一个在后台执行工作的 AsyncTask 类,现在可以为“启动任务”按钮实现 onClick 方法来触发后台任务;

doInBackground():实现代码以执行要在单独线程上执行的工作

onPostExecute():在doInBackground()执行结束后,自动在UI线程被调用,并接收doInBackground()的返回值。函数参数就是从doInBackground()中返回的结果

四、异步任务加载器

EditText,Button,TextView
需求:用户在 EditText 中输入书名并点击按钮,查询用户正在查找的图书的作者和书名,结果显示在 TextView 中

五、解决并发

  • 并发
    • 定义:指同一个时间段,程序中有多个代码片段同时运行或交替运行的情况;
  • 解决并发的基本操作
    • 核心:破坏同一时刻或同一目标;
    • 破坏同一时间的核心:排队;
    • 加锁:在变量 a 被一个线程读取后,就加一个锁,如果被写回来,就释放锁,其他线程过来后发现有锁,就等着;实现同时只有一个线程使用变量 a
    • 类比酒店入住,客人得到钥匙,并且锁门,这样别人就进不去了;离开再交还钥匙,下一个人就能入住了;即排队;
    • 加了锁之后,原来的并行(多个线程一起执行),变成了串行(线程排队执行)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个写代码的修车工

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值