多线程编程
在Android中系统要求网络访问必须在子线程中进行,否则会抛出异常,避免主线程被耗时操作阻塞而产生ANR
线程基础
进程与线程
什么是进程
进程是操作系统结构的基础,是程序在一个数据集合上运行的过程,是系统进行资源分配和调度的基本单位。
什么是线程
线程是操作系统调度的最小单元,也叫做轻量级进程,在一个进程中可以创建多个线程,这些线程都拥有各自的计数器、堆栈和局部变量等属性,并且能够访问共享的内存变量
线程的状态
Java线程在运行的生命周期中会有6种状态
- New:新创建状态。还没有调用start()方法
- Runnable:可运行状态。一旦调用start方法,线程就处于Runnable状态,一个可运行的线程可能正在运行也可能没有运行。取决于操作系统给线程提供的运行时间
- Blocked:阻塞状态,表示线程被锁阻塞
- Waiting:等待状态。表示线程暂时不活动
- Tiimed waiting:超时等待状态
-
Terminated:终止状态。表示当前线程已经执行完毕。
线程的状态
线程状态切换过程:
线程创建后,调用Thread的start方法,开始进入运行状态,当线程执行wait方法后,线程进入等待状态,进入等待状态的线程需要其他线程通知才能返回运行状态。超时等待相当于在等待状态加上了时间限制,如果超过时间限制,则线程返回运行状态。
创建线程
继承Thread类,重写run()方法
实现Runnable接口,实现该接口的run()方法
实现Callable接口,重写call()方法
Volatile
Volatile关键字为实例域的同步访问提供了免锁的机制。如果声明一个域为volatile,那么编译器和虚拟机就知道该域是可能被另一个线程并发更新的。
Java内存模型
Java中的堆内存用来存储对象实例,堆内存是被所有线程共享的运行时内存区域,因此堆内存存在内存可见性的问题。而局部变量、方法定义的参数则不会在线程之间共享,不会存在内存可见性问题,也不受内存模型的影响。
在Java中内存模型定义了线程和主存之间的抽象关系:线程之间的共享变量存储在主存中,每个线程都有一个私有的本地内存,本地内存中存储了该线程共享变量的副本。
Java内存模型的抽象示意图
线程A与B之间若要通信,要经历以下几个步骤:
- 线程A把线程A本地内存中更新过的共享变量刷新到主内存中去
- 线程B到主存中去读取线程A之前已更新过的共享变量
Volatile关键字
当一个共享变量被Volatile修饰之后,就具备了两个含义,
- 一个是线程修改了变量的值时,变量的新值对其他线程是立即可见的
- 禁止使用指令重排序,指令重排序是指编译器或运行时环境为了优化程序性能而采取的对指令进行重新排序的一种手段
volatile保证了操作的可见性、有序性,不保证原子性
线程池
线程池的处理流程线程池的种类
- FixedThreadPool
FixedThreadPool是可重用固定线程数的线程池 - CachedThreadPool
CachedThreadPool是一个根据需要创建线程的线程池 - SingleThreadExecutor
SingleThreadExecutor是使用单个工作线程的线程池
4.ScheduledThreadPool
ScheduledThreadPool是一个能实现定时和周期性任务的线程池
网友评论