多线程
首先了解多线程
应用程序(Application):为了完成特定任务,用某种语言编写的一组指令集合(一组静态代码)
-
进程:进程指正在运行的程序
- 系统调度与资源分配的一个独立单位
- 当一个程序进入内存运行,即变成一个进程
- 进程是处于运行过程中的程序,并且具有一定独立功能
-
线程:线程是进程中的一个执行单元,负责当前进程中程序的执行
- 一个进程中至少有一个线程
- 一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序
简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程
线程是由程序负责管理的
而进程则是由系统进行调度的
线程的生命周期
- 新建 :从新建一个线程对象到程序start() 这个线程之间的状态,都是新建状态;
- 就绪 :线程对象调用start()方法后,就处于就绪状态,等到JVM里的线程调度器的调度;
- 运行 :就绪状态下的线程在获取CPU资源后就可以执行run(),此时的线程便处于运行状态,运行状态的线程可变为就绪、阻塞及死亡三种状态。
- 等待/阻塞/睡眠 :在一个线程执行了sleep(睡眠)、suspend(挂起)等方法后会失去所占有的资源,从而进入阻塞状态,在睡眠结束后可重新进入就绪状态。
- 终止 :run()方法完成后或发生其他终止条件时就会切换到终止状态。
线程创建的一般方法
实现步骤 | 优势 | 劣势 | |
---|---|---|---|
继承Thread类 | ①、定义类继承Thread ②、复写Thread类中的run方法(目的:将自定义代码存储在run方法,让线程运行) ③、调用线程的start方法:该方法有两步:启动线程,调用run方法。 |
编写简单,可直接用this.getname()获取当前线程,不必使用Thread.currentThread()方法 | 已经继承了Thread类,无法再继承其他类 |
继承Thread类 | ①、定义类实现Runnable接口 ②、覆盖Runnable接口中的run方法(将线程要运行的代码放在该run方法中) ③、通过Thread类建立线程对象 ④、将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数(线程执行指定Runnable对象的run方法) ⑤、调用Thread类的start方法开启线程并调用Runnable接口子类的run方法 |
避免了单继承的局限性、多个线程可以共享一个target对象,非常适合多线程处理同一份资源的情形 | 比较复杂、访问线程必须使用Thread.currentThread()方法、无返回值 |
通过Callable和Future创建线程 | ①、创建Callable接口的实现类,并实现call()方法,改方法将作为线程执行体,且具有返回值 ②、创建Callable实现类的实例,使用FutrueTask类进行包装Callable对象,FutureTask对象封装了Callable对象的call()方法的返回值 ③、使用FutureTask对象作为Thread对象启动新线程 ④、调用FutureTask对象的get()方法获取子线程执行结束后的返回值 |
有返回值、避免了单继承的局限性、多个线程可以共享一个target对象,非常适合多线程处理同一份资源的情形 | 比较复杂、访问线程必须使用Thread.currentThread()方法 |
调用start()方法将会创建一个执行run()方法的线程
不管何种情况下,要想启动多线程,一定依靠Thread类完成
多线程应用在Android开发
- 继承Thread类
- 实现Runnable接口
- Handler
- AsyncTask
- HandlerThread
- IntentService
进程和线程的区别
根本区别
进程是操作系统资源分配的基本单位
线程是处理器任务调度和执行的基本单位
进程 | 线程 | |
---|---|---|
资源开销 | 每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销 | 线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小 |
包含关系 | 如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的 | 线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程 |
内存分配 | 进程之间的地址空间和资源是相互独立的 | 同一进程的线程共享本进程的地址空间和资源 |
影响关系 | 一个进程崩溃后,在保护模式下不会对其他进程产生影响 | 一个线程崩溃整个进程都死掉 |
执行过程 | 每个独立的进程有程序运行的入口、顺序执行序列和程序出口 | 线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制 |
多进程要比多线程健壮
两者均可并发执行
AsyncTask和Handler的区别
数据简单使用AsyncTask,实现代码简单,数据量多且复杂使用handler+thread
相比较AsyncTask来说能更好的利用系统资源且高效,但有些复杂逻辑比较难完成
AsyncTask实现的原理和适用的优缺点
AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主线程
-
使用的优点:
简单,快捷
过程可控
使用的缺点:
在使用多个异步操作和并需要进行Ui变更时,就变得复杂起来.
Handler异步实现的原理和适用的优缺点
在Handler 异步实现时,涉及到 Handler, Looper, Message,Thread四个对象,实现异步的流程是主线程启动Thread(子线程)运行并生成Message-Looper获取Message并传递给HandlerHandler逐个获取Looper中的Message,并进行UI变更
-
使用的优点:
结构清晰,功能定义明确
对于多个后台任务时,简单,清晰
使用的缺点:
在单个后台异步处理时,显得代码过多,结构过于复杂(相对性)