3.线程状态及其转化


3. 线程状态及其转化

线程是轻量级进程,所以线程和进程状态一致。

Java 线程状态转化图:

操作系统线程转换

3.1 Java 线程的 6 个状态

Thread.State 源码:

public enum State {
    NEW,                // 新创建的线程,未调用 start() 方法
    RUNNABLE,           // 线程正在运行中:可能是在 JVM 中运行,也可能在等待 CPU 时间片
    BLOCKED,            // 阻塞状态: 正等待锁的释放以进入同步区
    WAITING,            // 等待状态: 需要被其他线程唤醒才能重新进入 RUNNABLE 状态
    TIMED_WAITING,      // 超时等待状态: 等待一个具体的时间段,到期会被自动唤醒
    TERMINATED;         // 线程执行结束
}
  1. start() 方法只能调用一次,即使该线程已经执行完毕
    • threadStates 变量在 start() 方法未运行时为 0,第一次调用 start() 方法后,值会改变;而当线程执行完毕后,该变量会变成 2,代表线程 TERMINATED
  2. 以下情况会使线程进入 WAITING 状态:
    • Object.wait():使当前线程处于等待状态直到另一个线程唤醒它;
      • Object.wait() 会释放锁
    • Thread.join():让调用者等待当前线程执行完毕,底层调用的是 Object.wait()
    • LockSupport.park():除非获得调用许可,否则禁用当前线程进行线程调度。
  3. 以下情况会使线程进入 TIMED_WAITING 状态:
    • Thread.sleep(long millis):使当前线程睡眠指定时间;
      • sleep() 不会释放锁
    • Object.wait(long timeout):线程休眠指定时间,等待期间可以通过 notify()notifyAll() 唤醒;
      • notify() 会随机唤醒单个等待锁的线程
      • notify() 会唤醒所有等待锁的线程
    • Thread.join(long millis):等待当前线程最多 millis 毫秒,如果 millis=0,则不等待;
    • LockSupport.parkNanos(long nanos): 除非获得调用许可,否则在指定时间内禁止当前线程进行线程调度;
    • LockSupport.parkUntil(long deadline):与上面类似。

3.2 线程中断 interrupt()

Java 线程中断机制是一种协作机制。

  • 中断操作不能直接终止该线程的运行,而是把对应线程的中断状态设置为 true,然后被中断的线程可以选择如何去处理中断请求,或者不处理中断,继续执行下去

3.2.1 Java 中线程中断的方法

  • Thread.interrupt():中断线程。并不会立即停止线程,而是设置线程的中断状态为 true(默认是 false);
  • Thread.interrupted():测试当前线程是否被中断,返回线程当前的中断标志位。调用该方法会影响线程的中断状态:
    • 调用 interrupted() 方法会反转线程的中断状态。
  • Thread.isInterrupted():测试当前线程是否被中断。
    • 调用这个方法不会影响线程的中断状态。

3.3 join()

如果一个线程实例 A 执行了 threadB.join(), 其含义是:当前线程 A 会等待 threadB 线程终止后 threadA 才会继续执行。

3.4 sleep()

sleep() 会使线程休眠,只是让出 CPU 使用权,但不会放弃锁。

3.5 wait()

wait() 方法必须在同步方法或者同步块中执行,即线程必须已经获得了锁。

wait() 方法调用会释放锁,线程会进入等待池,遇到 notify()notifyAll() 后,才会离开等待池,变成可运行状态。

3.6 yield()

方法调用后,该线程会让出 CPU 使用权,重新参与 CPU 时间片的竞争。

  • 线程从 Running 状态转变为 Runnable 状态。
  • 下一次 CPU 时间片会根据线程优先级来确定,也可能该线程在让出 CPU 后,还会立即获得 CPU 时间片
  • 只能使同优先级的线程有执行的机会

文章作者: Yu Yang
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Yu Yang !
 上一篇
编译与优化 编译与优化
1. 逃逸分析逃逸是指一个对象在某个方法中被创建后,会被其他方法或其他线程所引用。 方法逃逸:该对象被作为参数传递到其他方法中。 线程逃逸:该对象被关联到其他线程中可以访问到的实例变量中。 线程逃逸的逃逸程度比方法逃逸更高。 如果能证明
2020-11-07
下一篇 
内存模型 JMM 内存模型 JMM
6. Java 内存模型6.1 并发模型线程间进行通信和同步,可以通过 2 种方式的并发模型来实现: 消息传递并发模型 共享内存并发模型 Java 中,采用的是第二种:共享内存并发模型 6.2 JVM 运行时数据区 方法区 和 堆,
  目录