Android 多线程

Android沿用了Java的线程模型,一个Android应用在创建的时候会开启一个线程,我们叫它主线程或者UI线程。如果我们想要访问网络或者数据库等耗时的操作时,都会开启子线程去处理,从Android 3.0开始,系统要求网络访问必须在子线程中进行,否则会抛出异常;也就是为了避免主线程被耗时操作阻塞从而产生ANR,同时也说明了多线程在Android应用开发占据着十分重要的位置。《Android进阶之光》

进程与线程

  1. 进程
    1. 一个“进行中”的程序。
    2. 系统进行资源分配和调度的基本单位。
  2. 线程
    1. CPU调度的最小单元。
    2. 与进程相比,线程创建和切换开销更小。

Java线程的状态(6种)

网上5种状态的说法误导的,5种状态是属于早期进程的状态。

下面是JDK源码:src/main/java/java/lang/Thread.java 中 线程状态State枚举 代码:

1
2
3
4
public enum State {  
NEW, RUNNABLE, BLOCKED, WAITING,
TIMED_WAITING, TERMINATED;
}
  1. New:新建线程,还未调用start()方法。
  2. Runnbale:就绪状态,或者叫可运行状态。Runnable是包括Ready和Running状态的,因为CPU时间片的非常快的,Ready和Running状态在Java线程是没必要的。
  3. Blocked:阻塞状态。
  4. Waiting:等待状态。线程暂时不活动,并且不运行任何代码,这消耗最少的资源,直到线程调度器重新激活它。
  5. Timed waiting:超时等待状态。和等待状态不同的是,它是可以在指定的时间自行返回的。
  6. Terminated:终止状态。表示当前线程已经执行完毕。导致线程终止有两种情况:
    1. run方法(执行体)执行完毕正常退出;
    2. 没有捕获的异常而终止了run方法(执行体),导致线程进入终止状态。

NeatReader-1661542439083.png

线程的创建方式

  1. 继承Thread类,重写run()方法
  2. 实现Runnable接口,并实现该接口的run()方法
  3. 实现Callable接口,重写call()方法

线程的中断

  1. 当线程的run方法执行完毕,或者在方法中出现没有捕获的异常时,线程将终止。
  2. 在Java早期版本中有一个stop方法,其他线程可以调用它终止线程,但是这个方法现在已经被弃用了。

Java内存模型JMM

线程同步

  1. 重入锁与条件对象:Lock/Condition
  2. synchronized、Object.wait()、Object.notify()\notifyAll()
  3. volatile关键字
    1. 保证可见性
    2. 禁止指令重排
      1. 编译期重排序
      2. 运行期重排序
    3. 不保证原子性

阻塞队列

在Java中提供了7个阻塞队列,它们分别如下所示。

  1. ArrayBlockingQueue:由数组结构组成的有界阻塞队列。
  2. LinkedBlockingQueue:由链表结构组成的有界阻塞队列。
  3. PriorityBlockingQueue:支持优先级排序的无界阻塞队列。
  4. DelayQueue:使用优先级队列实现的无界阻塞队列。
  5. SynchronousQueue:不存储元素的阻塞队列。
  6. LinkedTransferQueue:由链表结构组成的无界阻塞队列。
  7. LinkedBlockingDeque:由链表结构组成的双向阻塞队列。

线程池

线程池

AsyncTask

AsyncTask