线程的生命周期包括:新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Dead)5种状态。线程状态转换图如下:

 1、新建状态(New)

 当程序使用new关键字创建一个线程后,Java虚拟机为其分配内存,并初始化其成员变量的值,此时处于新建状态,程序不会执行线程的线程执行体run()。

 2、就绪状态(Runnable)

当线程对象调用了start()方法后,该线程就处于就绪状态,此时Java虚拟机会为其创建方法调用栈和程序计数器,处于此状态的线程只是表示该线程可以运行了,至于何时开始运行,则取决与JVM里线程调度器的调度。线程已经被启动,正在等待被分配给CPU时间片,也就是说此时线程正在就绪队列中排队等候得到CPU资源。

 注意:不能对已经启动的线程再次调用start()方法,否则会出现java.lang.IllegalThreadStateException异常。如果希望子线程调用start()方法后立即执行,可以使用Thread.sleep(1)方式使主线程睡眠1毫秒,转去执行子线程,因为这1毫秒内CPU不会空闲,它会去执行另一个就绪的线程。

 3、运行状态(Running)

 线程获得CPU资源正在执行任务(run()方法),此时除非此线程自动放弃CPU资源或者有优先级更高的线程进入,线程将一直运行到结束。对于抢占式策略的系统而言,系统会给每个线程一个小时间段来处理任务,当该时间段用完后,系统会剥夺该线程占用的资源,让其他线程获得执行的机会(考虑优先级)。

 如果该线程失去了cpu资源,就会又从运行状态变为就绪状态。重新等待系统分配资源。也可以对在运行状态的线程调用yield()方法,它就会让出cpu资源,再次变为就绪状态。

当发生如下情况是,线程会从运行状态变为阻塞状态:

①、线程调用sleep()方法主动放弃所占用的系统资源。

②、线程调用一个阻塞式IO方法,在该方法返回之前,该线程被阻塞。

③、线程试图获得一个同步锁,但该资源被其他线程占有。

④、线程在等待某个通知(notify)。

⑤、程序调用了线程的suspend()方法将线程挂起。不过该方法容易导致死锁,所以程序应该尽量避免使用该方法。

当线程的run()/call()方法执行完,或者被强制性地终止,例如出现异常,或者调用了stop()方法等等,就会从运行状态转变为死亡状态。

 4、阻塞状态(Running)

 由于某种原因导致正在运行的线程让出CPU资源并暂停自己的执行,即进入堵塞状态。如上面讲到的5点都能将运行状态的线程转换为阻塞状态。在阻塞状态的线程不能进入就绪队列,只有当引起阻塞的原因解除后,线程便转入就绪状态,重新到就绪队列中排队,等待线程调度器再次调度。解除阻塞的几种情况:

①、调用sleep()方法线程经过了指定时间。

②、调用的阻塞式IO方法已经返回。

③、线程成功获得申请的同步锁。

④、线程在等待某个通知(notify)时,其他线程发出了一个通知。

⑤、处于挂起状态的线程被调用了resume()恢复方法。

 5、死亡状态(Dead)

 线程会以如下3种方式结束,结束后就处于死亡状态。

 ①、run()或call()方法执行完成,线程正常结束。

②、线程抛出一个未捕获的Exception或Error。

③、直接调用线程的stop()方法来结束线程——该方法容易导致死锁,通常不推荐使用。

 注意:可调用线程对象的isAlive()方法,测试线程是否死亡(线程处于就绪、运行、阻塞3种状态时返回true)。同理,不能对已经死亡的线程再次调用start()方法,否则会出现java.lang.IllegalThreadStateException异常。

 关于yeild()方法的使用,请看下一篇《线程的控制》。

Java线程的生命周期的更多相关文章

  1. Java线程的生命周期(转)

    Java线程的生命周期 一个线程的产生是从我们调用了start方法开始进入Runnable状态,即可以被调度运行状态,并没有真正开始运行,调度器可以将CPU分配给它,使线程进入Running状态,真正 ...

  2. 【Java并发基础】Java线程的生命周期

    前言 线程是操作系统中的一个概念,支持多线程的语言都是对OS中的线程进行了封装.要学好线程,就要搞清除它的生命周期,也就是生命周期各个节点的状态转换机制.不同的开发语言对操作系统中的线程进行了不同的封 ...

  3. 图解Java线程的生命周期,看完再也不怕面试官问了

    文章首发自个人微信公众号: 小哈学Java https://www.exception.site/java-concurrency/java-concurrency-thread-life-cycle ...

  4. java线程的生命周期及五种基本状态

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

  5. Java—线程的生命周期及线程控制方法详解

    线程生命周期5种状态 介绍   线程的生命周期经过新建(New).就绪(Runnable).运行(Running).阻塞(Bolocked)和死亡(Dead) 状态转换图 新建(New)   程序使用 ...

  6. Java线程之生命周期

    简述 以下类图展示了线程生命周期中不同的状态.我们可以创建一个线程并启动它,但是线程状态从Runnable.Running.Blocked等状态的变化取决于系统线程调度器,java本身并不能完全控制. ...

  7. Java 线程的生命周期

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

  8. Java线程的生命周期与状态流转

    上图是一个线程的生命周期状态流转图,很清楚的描绘了一个线程从创建到终止的过程. 这些状态的枚举值都定义在java.lang.Thread.State下 NEW:毫无疑问表示的是刚创建的线程,还没有开始 ...

  9. 深入Java线程管理(二):线程的生命周期

    Java线程的生命周期 一个线程的产生是从我们调用了start方法开始进入Runnable状态,即可以被调度运行状态,并没有真正开始运行,调度器可以将CPU分配给它,使线程进入Running状态,真正 ...

随机推荐

  1. 使用WebView视图显示网页-----迷你浏览器

    Android提供了WebView组件,表面上来看,这个组件与普通ImageView差不多,但实际上,这个组件的功能要强大得多,WebView组件本身就是一个浏览器实现,它的内核基于开源WebKit引 ...

  2. OpenGL 和OpenGL ES简介

    OpenGL的全称是Open  Graphics  Library,即开放的图形库接口,它定义了一个跨编程语言.跨平台的编程接口的规范,它主要用于三维图形(实际上二维图形也可以)变成.OpenGL的前 ...

  3. 二模 (11) day1

    第一题: 题目大意:用邻接矩阵给出一棵树(边权非负)上N个节点相互之间的最短路距离,求这棵树所有边权的和. 解题过程: 1.暂时还没想出来,待AC. 第二题: 题目大意:给出一些单词,然后建立Trie ...

  4. 使用ASP.Net WebAPI构建REST服务(二)——路由

    REST并没有像传统的RPC服务那样显式指定了服务器函数的访问路径,而是将URL根据一定的规则映射为服务函数入口,这个规则就称之为路由.Asp.Net WebAPI的路由方式和Asp.Net MVC是 ...

  5. ionic build --release android

    ionic bulid android ionic build --release android keytool -genkey -v -keystore demo.keystore -alias ...

  6. POJ 2104 静态找区间第k大

    静态区间第k大的问题,往往可以利用主席树来解决 这是主席树的第一道题 主席树大概可以理解为在n个节点上都建立一棵线段树,但是想想会超出内存 每一个节点保存的线段树都记录当前整段前缀区间的信息 但是因为 ...

  7. 手机app常见bug积累

    经过一年的测试工作,以下是手机APP比较容易出现的错误.之后如果发现了还会继续添加,修改.1.翻页手机客户端,内容超过一页时,上拉加载更多内容,加载错误(容易出现数据重复,图片和文章不匹配,图片重复加 ...

  8. Java选择结构、循环结构

    1:switch语句(掌握) (1)格式: switch(表达式) { case 值1: 语句体1; break; case 值2: 语句体2; break; ... default: 语句体n+1; ...

  9. init()和deinit()

    一.初始化方法(init()) 1.定义:类初始化对象时所调用的方法 2.分类: (1)默认初始化方法 (2)便利初始化方法 (3)使用闭包 3.一些注意点: (1)方法固定名为init,没有返回值, ...

  10. Ubuntu 14.10 下安装MySQL

    在Ubuntu上安装MySQL很简单,只需要几个命令行 1 安装服务器 sudo apt-get install mysql-server 2 安装客户端 sudo apt-get install m ...