线程的生命周期包括:新建(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. function format_number(srcNumber, n) {

    function format_number(srcNumber, n) {var dstNumber = parseFloat(srcNumber);if (isNaN(dstNumber)) {r ...

  2. poj 3468 A Simple Problem with Integers 线段树第一次 + 讲解

    A Simple Problem with Integers Description You have N integers, A1, A2, ... , AN. You need to deal w ...

  3. 关于Tcp,为什么一定要进行三次握手呢?

    主要是防止已经失效的请求报文段突然又传送到了服务端而产生的连接的误判. 考虑如下的情况:客户端发送了一个连接请求报文段到服务端,但是在某些网络节点上长时间滞留了,而后客户端又超时重发了一个连接请求报文 ...

  4. WP8.1 Study4:WP8.1中控件集合应用

    1.AutoSuggestBox的应用 在xaml里代码可如下: <AutoSuggestBox Name="autobox" Header="suggestion ...

  5. struts中拦截器的开发

    1.开发Interceptor类 用户自定义的拦截器一般需要继承AbstractInterceptor类,重写intercept方法 public class UserInterceptor exte ...

  6. 关于java中super()和this()

    在java中this表示当前类中的对象,super则表示父类中的对象.比如当前对象的某个方法,或当前对象的某个成员,你便可以利用this来实现这个目的,当然,this的另一个用途是调用当前对象的另一个 ...

  7. jsp福利哟

    Servlet与JSP九大内置对象的关系 JSP对象 怎样获得 out->response.getWriter request ->Service方法中的req参数 response -& ...

  8. iOS开发中的远程推送实现(最新,支持iOS9)

    我的个人项目<丁丁印记>中加入了远程推送功能,按照操作说明去做还是比较容易实现的,但是学的不够不系统,而且iOS8之后的推送和之前的版本是有所不同的,因此这篇文章希望总结一下最新的iOS推 ...

  9. java基础-005

    27.Java中垃圾回收的目的及回收的时机 垃圾回收的目的是识别并且丢弃不再使用的对象来释放和重用资源. 如果对象的引用被置为null,垃圾收集器不会立即释放对象占用的内存. 什么时候进行垃圾回收,主 ...

  10. ThinkPHP中Session用法详解

    在ThinkPHP封装了Session类,用户可以直接使用,常用的方法有: Session::set(name, value):注册 session . Session::is_set(name):检 ...