华为技术专家深度解析Java线程状态(上)

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 华为技术专家深度解析Java线程状态

JDK 的 Thread 源码定义了6个状态: java.lang.Thread.State

  • New
    尚未启动的线程的线程状态。
  • Runnable
    可运行线程的线程状态,等待CPU调度。
  • Blocked
    线程阻塞等待监视器锁定的线程状态。处于synchronized同步代码块或方法中被阻塞。
  • Waiting
    等待线程的线程状态。下列不带超时的方式:
    Object.waitThread.joinLockSupport.park
  • Timed Waiting具有指定等待时间的等待线程的线程状态。下列带超时的方式:Thread.sleep、0bject.wait、 Thread.join、 LockSupport.parkNanos、 LockSupport.parkUntil、
  • Terminated
    终止线程的线程状态。线程正常完成执行或出现异常。


文字说的还不是太清楚了,让我来你画个图就一目了然了:


  • Thread状态机

image.png

  • 上面那个图太复杂了看不懂?没问题,看个小学生版:

1.png

1 NEW

  • 线程还没有开始执行

image.png

实现Runnable接口和继承Thread可以得到一个线程类,new一个实例出来,线程就进入了 NEW 状态。


当调用线程的start()方法,线程也不一定会马上执行,因为Java线程是映射到os的线程执行的,此时可能还需要等os调度,但此时该线程的状态已经为RUNNABLE

image.png

2 RUNNABLE

image.png

只是说你有资格运行,调度程序没有挑选到你,你就永远是可运行状态。

2.1条件

  • 调用start()
  • Thread.sleep(long millis)

image.png

一定是当前线程调用此方法,当前线程进入阻塞,不释放对象锁,millis后线程自动苏醒进入可运行态。

作用:给其它线程执行机会的最佳方式。

  • 其他线程join()结束

当前线程里调用其它线程1的join方法,当前线程阻塞,但不释放对象锁,直到线程1执行完毕或者millis时间到,当前线程进入可运行状态。

  • 等待用户输入完毕
  • 某个线程拿到对象锁
  • 当前线程时间片用完
  • Thread.yield()

image.png

调用当前线程的yield()

一定是当前线程调用此方法,当前线程放弃获取的cpu时间片,由运行状态变会可运行状态,让os再次选择线程。


作用:让同优先级的线程轮流执行,但并不保证一定会轮流执行。实际无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。Thread.yield()不会导致阻塞。


  • 锁池里的线程拿到对象锁后,进入可运行状态
  • 正在执行的线程


该状态最有争议,注释说它表示线程在JVM层面是执行的,但在os不一定,它举例是CPU,毫无疑问CPU是一个os资源,但这也就意味着在等os其它资源时,线程也会是这个状态。


I/O阻塞算是等os的资源?

3 BLOCKED

  • 线程由于等待监视器锁,被阻塞。 处于阻塞态的线程在调用Object.wait之后正在等待监视器锁 进入 同步的块/方法或 再进入 同步的块/方法

image.png

被挂起,线程因为某原因放弃cpu 时间片,暂时停止运行。

3.1条件

  • 当前线程调用Thread.sleep()
  • 运行在当前线程里的其它线程调用join(),当前线程进入阻塞态
  • 等待用户输入时,当前线程进入阻塞态

3.2 分类

  • 等待阻塞
    运行的线程执行o.wait()方法,JVM会把该线程放入等待队列(waitting queue)
  • 同步阻塞

运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)

  • 其他阻塞

运行的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。


当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。


线程在阻塞等待monitor lock(监视器锁)

一个线程在进入synchronized修饰的临界区的时候,或者在synchronized临界区中调用Object.wait然后被唤醒重新进入synchronized临界区都对应该态。


结合上面RUNNABLE的分析,也就是I/O阻塞不会进入BLOCKED状态,只有synchronized会导致线程进入该状态


关于BLOCKED状态,注释里只提到一种情况就是进入synchronized声明的临界区时会导致,这好理解,synchronized是JVM自己控制的,所以这个阻塞事件它自己能够知道(对比理解上面的os层面)。


interrupt()是无法唤醒的,只是做个标记。


目录
相关文章
|
1月前
|
并行计算 Java 数据处理
SpringBoot高级并发实践:自定义线程池与@Async异步调用深度解析
SpringBoot高级并发实践:自定义线程池与@Async异步调用深度解析
166 0
|
20天前
|
安全 程序员 API
|
17天前
|
存储 设计模式 分布式计算
Java中的多线程编程:并发与并行的深度解析####
在当今软件开发领域,多线程编程已成为提升应用性能、响应速度及资源利用率的关键手段之一。本文将深入探讨Java平台上的多线程机制,从基础概念到高级应用,全面解析并发与并行编程的核心理念、实现方式及其在实际项目中的应用策略。不同于常规摘要的简洁概述,本文旨在通过详尽的技术剖析,为读者构建一个系统化的多线程知识框架,辅以生动实例,让抽象概念具体化,复杂问题简单化。 ####
|
2月前
|
存储 缓存 Java
什么是线程池?从底层源码入手,深度解析线程池的工作原理
本文从底层源码入手,深度解析ThreadPoolExecutor底层源码,包括其核心字段、内部类和重要方法,另外对Executors工具类下的四种自带线程池源码进行解释。 阅读本文后,可以对线程池的工作原理、七大参数、生命周期、拒绝策略等内容拥有更深入的认识。
142 29
什么是线程池?从底层源码入手,深度解析线程池的工作原理
|
28天前
|
安全 Java
Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧
【10月更文挑战第20天】Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧,包括避免在循环外调用wait()、优先使用notifyAll()、确保线程安全及处理InterruptedException等,帮助读者更好地掌握这些方法的应用。
17 1
|
1月前
|
Java 开发者 UED
Java中的异常处理:从新手到专家
【10月更文挑战第9天】在Java的编程世界中,异常处理是每个开发者必须面对的挑战。本文将引导你从基础的异常理解到高级的处理技巧,通过具体代码示例,展示如何优雅地管理程序中可能出现的错误和异常情况。无论你是刚开始学习Java,还是希望提高你的异常处理能力,这篇文章都将为你提供宝贵的知识和技巧。
|
1月前
|
Java 程序员
Java中的异常处理:从新手到专家
【10月更文挑战第9天】在Java的世界中,异常处理就像是驾驶时的方向盘,掌握它,你就能驾驭代码的运行方向。本文将通过深入浅出的方式,带你了解Java异常处理的奥秘,从基本的try-catch语句到自定义异常类的创建,让你的代码更加健壮和易于维护。
12 2
|
2月前
|
缓存 Java 应用服务中间件
Java虚拟线程探究与性能解析
本文主要介绍了阿里云在Java-虚拟-线程任务中的新进展和技术细节。
105 23
|
1月前
|
安全 Java 数据库连接
Python多线程编程:竞争问题的解析与应对策略
Python多线程编程:竞争问题的解析与应对策略
22 0
|
1月前
|
安全 Java 数据库连接
Python多线程编程:竞争问题的解析与应对策略【2】
Python多线程编程:竞争问题的解析与应对策略【2】
26 0

推荐镜像

更多