一、线程的生命周期及五种基本状态

关于Java中线程的生命周期,首先看一下下面这张较为经典的图:

上图中基本上囊括了Java中多线程各重要知识点。掌握了上图中的各知识点,Java中的多线程也就基本上掌握了。主要包括:

Java线程具有七种基本状态

新建状态(New):至今尚未启动的线程的状态。线程刚被创建,但尚未启动。如:Thread t = new MyThread();

就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;

运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就     绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;

无限期等待(Waiting):位于对象等待池中的阻塞状态(Blocked in object’s wait pool):当线程处于运行状态时,如果执行了某个对象的wait()方法,Java虚拟机就会把线程放到这个对象的等待池中,这涉及到“线程通信”的内容。处于这种状态的线程不会被分配处理器执行时间,它们要等待被其他线程显示唤醒。以下方法会让线程陷入无限期的等待状态:

没有设置timeout参数的Object::wait()方法

没有设置timeout参数的Thread::join()方法

LockSupport::park()方法

限期等待(Timed Waiting):处于这种状态的线程也不会被分配处理器执行时间,不过无须等待其他线程显示唤醒,在一定时间后它们由系统自动唤醒。以下方法会让线程进入期限等待状态:

Thread::sleep()方法

设置了timeout参数的Object::wait()方法

设置了timeout参数的Thread::join()方法

LockSupport::parkNanos()方法

LockSupport::parkUntil()方法

阻塞状态(Blocked):处于运行状态中的线程由于某种(当线程处于运行状态时,试图获得某个对象的同步锁时,如果该对象的同步锁已经被其他线程占用,Java虚拟机就会把这个线程放到这个对象的锁池中,这涉及到“线程同步”的内容。【线程在获取synchronized同步锁失败(因为锁被其它线程所占用)】)原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才有机会再次被CPU调用以进入到运行状态。

“阻塞状态”与“等待状态”的区别:“阻塞状态”在等待着获取一个排它锁,这个事件将在另一个线程放弃这个锁的时候发生;而“等待状态”则是在等待一段时间,或者唤醒动作发生。在程序进入同步区域的时候,线程就会进入阻塞状态。

死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

JVM线程运行状态 (JVM Thread Status)

至今尚未启动的线程的状态。线程刚被创建,但尚未启动。

可运行线程的线程状态。线程正在JVM中执行,有可能在等待操作系统中的其他资源,比如处理器。

受阻塞并且正在等待监视器的某一线程的线程状态。处于受阻塞状态的某一线程正在等待监视器锁,以便进入一个同步的块/方法,或者在调用 Object.wait 之后再次进入同步的块/方法。在Thread Dump日志中通常显示为 java.lang.Thread.State: BLOCKED (on object monitor) 。

某一等待线程的线程状态。线程正在无期限地等待另一个线程来执行某一个特定的操作,线程因为调用下面的方法之一而处于等待状态:

不带超时的 Object.wait 方法,日志中显示为 java.lang.Thread.State: WAITING (on object monitor)

不带超时的 Thread.join 方法

LockSupport.park 方法,日志中显示为 java.lang.Thread.State: WAITING (parking)

指定了等待时间的某一等待线程的线程状态。线程正在等待另一个线程来执行某一个特定的操作,并设定了指定等待的时间,线程因为调用下面的方法之一而处于定时等待状态:

Thread.sleep 方法

指定超时值的 Object.wait 方法

指定超时值的 Thread.join 方法

LockSupport.parkNanos

LockSupport.parkUntil

线程处于终止状态。

根据Java Doc中的说明,在给定的时间上,一个只能处于上述的一种状态之中,并且这些状态都是JVM的状态,跟操作系统中的线程状态无关。

JAVA虚拟机启动程序步骤:

(1) Main是启动时候的主线程,即程序入口

(2) 在main函数结束后,虚拟机会自动启动一个DestroyJavaVM线程,该线程会等待所有user thread 线程结束后退出(即,只剩下daemon 线程和DestroyJavaVM线程自己,整个虚拟机就退出,此时daemon线程被终止),因此,如果不希望程序退出,只要创建一个非daemon的子线程,让线程不停的sleep即可。

线程的创建

Thread类,有一个start方法,即启动该线程。 启动的线程会执行该类的run方法。注意:因为启动线程时要执行某个过程,因此,通常是需要重新实现run方法的

线程的结束

run模块执行完成主动退出,或者被其他线程强行终止。

通过jstack pid >1.txt

线程状态样例

等待状态样例

上面例子中,IoWaitThread 线程保持等待状态并从 LinkedBlockingQueue 接收消息,如果 LinkedBlockingQueue 一直没有消息,该线程的状态将不会改变。

阻塞状态样例

在上面的例子中,BLOCKED_TEST pool-1-thread-1 线程占用了 <0x0000000780a000b0> 锁,然而 BLOCKED_TEST pool-1-thread-2 和 BLOCKED_TEST pool-1-thread-3 threads 正在等待获取锁。

死锁状态样例

上面的例子中,当线程 A 需要获取线程 B 的锁来继续它的任务,然而线程 B 也需要获取线程 A 的锁来继续它的任务的时候发生的。在 thread dump 中,你能看到 DEADLOCK_TEST-1 线程持有 0x00000007d58f5e48 锁,并且尝试获取 0x00000007d58f5e60 锁。你也能看到 DEADLOCK_TEST-2 线程持有 0x00000007d58f5e60,并且尝试获取 0x00000007d58f5e78,同时 DEADLOCK_TEST-3 线程持有 0x00000007d58f5e78,并且在尝试获取 0x00000007d58f5e48 锁,如你所见,每个线程都在等待获取另外一个线程的锁,这状态将不会被改变直到一个线程丢弃了它的锁。

无限等待的Runnable状态样例

上例中线程的状态是RUNNABLE,但在下面的堆栈日志中发现socketReadThread 线程正在无限等待读取 socket,因此不能单纯通过线程的状态来确定线程是否处于阻塞状态,应该根据详细的堆栈信息进行分析。

java threadstatus_Thread之一:线程生命周期及六种状态相关推荐

  1. 线程生命周期及六种状态

    一.线程的生命周期及五种基本状态 关于Java中线程的生命周期,首先看一下下面这张较为经典的图: 上图中基本上囊括了Java中多线程各重要知识点.掌握了上图中的各知识点,Java中的多线程也就基本上掌 ...

  2. java中线程的生命周期_Java中的线程生命周期– Java中的线程状态

    java中线程的生命周期 Understanding Thread Life Cycle in Java and Thread States are very important when you a ...

  3. java线程6种状态转换,Java线程的生命周期和各种状态转换详解

    在Java中,任何对象都有生命周期,线程也不例外,它也有自己的生命周期.当Thread对象创建完成时,线程的生命周期便开始了,当线程任务中代码正常执行完毕或者线程抛出一个未捕获的异常(Exceptio ...

  4. java并发编程基础—生命周期与线程控制

    一.线程生命周期 线程被创建启动以后,他既不是一启动就进入执行状态,也不是一直处于执行状态,在线程的生命周期中,它要经过新建(New).就绪(Runnable).运行(Running).阻塞(Bloc ...

  5. 【JAVA多线程学习笔记】(1)实现线程的方式 线程生命周期 操作线程的方法

    文章目录 两种方式实现线程 继承Thread类 模拟银行叫号的程序 Runnable接口 代码1:(与swing相结合创建gui程序) Thread类的⼏个常⽤⽅法 线程生命周期 操作线程的方法 代码 ...

  6. java线程基础巩固---线程生命周期以及start方法源码剖析

    上篇中介绍了如何启动一个线程,通过调用start()方法才能创建并使用新线程,并且这个start()是非阻塞的,调用之后立马就返回的,实际上它是线程生命周期环节中的一种,所以这里阐述一下线程的一个完整 ...

  7. java resume过时方法_面试官没想到,一个 Java 线程生命周期,我可以扯半小时

    面试官:你不是精通 Java 并发吗?从基础的 Java 线程生命周期开始讲讲吧. 好的,面试官.吧啦啦啦... 如果要说 Java 线程的生命周期的话,那我觉得就要先说说操作系统的线程生命周期 因为 ...

  8. java不同进程的相互唤醒_Java线程生命周期与状态切换

    前提 最近有点懒散,没什么比较有深度的产出.刚好想重新研读一下JUC线程池的源码实现,在此之前先深入了解一下Java中的线程实现,包括线程的生命周期.状态切换以及线程的上下文切换等等.编写本文的时候, ...

  9. 详解Java线程生命周期与状态切换

    前提 最近有点懒散,没什么比较有深度的产出.刚好想重新研读一下JUC线程池的源码实现,在此之前先深入了解一下Java中的线程实现,包括线程的生命周期.状态切换以及线程的上下文切换等等.编写本文的时候, ...

最新文章

  1. 老罗android oat,入门ART虚拟机(5)——OAT文件
  2. 【FZU - 2039】Pets(二分图匹配,水题)
  3. 独家下载 |《领军行业大数据及AI实战》解锁九大行业领军企业云上大数据及AI实战
  4. java分治法求数列的最大子段和_同事为进大厂天天刷Java面试题,面试却履败!究其原因竟是它在捣鬼。...
  5. 陌陌怎么发起群活动 陌陌群组发起群活动教程
  6. Android初级教程初谈自定义view自定义属性
  7. 使用多线程与不使用多线程访问同一个网址实例对比
  8. freebsd 运行linux,Freebsd 下运行 QQ For Linux 的方法
  9. 如何在ROS环境中解码.bag格式数据
  10. CTF---Web入门第二题 上传绕过
  11. 步进电机正反转实验_电机正反转控制电路图原理图解
  12. 创意字体设计,创意思路哪里找
  13. 计算机桌面的任务栏,计算机桌面出现两个任务栏怎么办?
  14. 基于SSM毕业生就业管理系统
  15. 用幻灯片征服全世界_NET为什么会征服世界NET很显然很像
  16. K-Means(K-均值)聚类算法
  17. 计算机叶老师,叶茫 - 教师简历 CV- 武汉大学计算机学院
  18. sublime安装和使用
  19. MySQL讲义第 39 讲——select 查询之函数(2):日期时间型函数
  20. TcpListener和TcpClient传输文件

热门文章

  1. 区块链在供应链领域的应用
  2. ubuntu16安装go语言
  3. 阿里巴巴计算平台资深技术专家“一浪”对大数据领域近几年的技术趋势和变化的看法【强烈推荐数据岗细细品!】
  4. 使用Lombok简化开发及无效解决方案
  5. 对于多表查询和转账的事务提交
  6. leetcode 752. Open the Lock | 752. 打开转盘锁(BFS)
  7. Gitee ssh 公钥配置好后,仍然 permission denied 的排查过程及解决方法
  8. leetcode 926. Flip String to Monotone Increasing | 926. 将字符串翻转到单调递增(前缀和)
  9. 【Git】切换分支,以及git stash的使用
  10. Python基础之:数字字符串和列表