并发和多线程(三)--线程的生命周期/状态

  线程的生命周期或者说状态其实不复杂,但是很多人的理解可能有错误,一个典型的误区,线程运行时的状态是Runnable,而不是Running,因为线程

没有Running状态。

线程的状态

1、New:已创建,没启动。还没有执行start()

2、Runnable:调用start()之后就处于Runnable,无论是否已经运行,都是Runnable状态,对应操作系统的Ready和Running状态。

3、Blocked:进入Synchronized修饰的方法或者代码块,但是无法获取锁,就处于Blocked。

4、Waiting:线程进入等待的阻塞状态,例如调用Object.wait()。

5、Timed-Waiting:线程进入计时等待的阻塞状态,例如调用Thread.sleep(time)。

6、Terminated:线程执行代码结束,或者出现未捕捉的异常。

PS:线程没有Running状态,请参考官方文档:https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.State.html

线程的状态转换

从上图,可以明确看到状态如何进行转换,状态之间的变化是否可逆。。。

验证线程状态

为了上面所讲线程状态的可信度,我们通过代码进行验证

1、New、Runnable、Terminated

public static void main(String[] args) throws InterruptedException{
    Thread thread = new Thread(() -> {
        for (int i = 0; i <= 4; i++) {
            log.info("{}", i);
            if (i == 2) {
                log.info("子线程运行过程中状态:{}", Thread.currentThread().getState());
            }
        }
    });

    log.info("子线程没有执行start时,状态:{}", thread.getState());
    thread.start();
    log.info("子线程执行start后,状态:{}", thread.getState());
    Thread.sleep(10);
    log.info("子线程执行结束,状态:{}", thread.getState());
}
结果:
17:12:11.244 [main] INFO com.diamondshine.Thread.ThreadClass - 子线程没有执行start时,状态:NEW
17:12:11.251 [main] INFO com.diamondshine.Thread.ThreadClass - 子线程执行start后,状态:RUNNABLE
17:12:11.251 [Thread-0] INFO com.diamondshine.Thread.ThreadClass - 0
17:12:11.251 [Thread-0] INFO com.diamondshine.Thread.ThreadClass - 1
17:12:11.251 [Thread-0] INFO com.diamondshine.Thread.ThreadClass - 2
17:12:11.252 [Thread-0] INFO com.diamondshine.Thread.ThreadClass - 子线程运行过程中状态:RUNNABLE
17:12:11.252 [Thread-0] INFO com.diamondshine.Thread.ThreadClass - 3
17:12:11.252 [Thread-0] INFO com.diamondshine.Thread.ThreadClass - 4
17:12:11.262 [main] INFO com.diamondshine.Thread.ThreadClass - 子线程执行结束,状态:TERMINATED

成功验证了在子线程执行过程中的状态是Runnable,而不是Running。

2、Blocked、Waiting、Time-Waiting

@Slf4j
public class ThreadClass implements Runnable{

    public static void main(String[] args) throws InterruptedException{

        ThreadClass threadClass = new ThreadClass();
        Thread thread = new Thread(threadClass);
        thread.start();
        Thread thread1 = new Thread(threadClass);
        thread1.start();

        //sleep 5ms为了让子线程执行到synchronize()的Thread.sleep(1000)
        try {
            Thread.sleep(5);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        log.info("第一个线程的状态:{}", thread.getState());
        //此时第一个线程获取monitor锁,然后休眠1000ms,所以第二个线程无法获得锁
        log.info("第二个线程的状态:{}", thread1.getState());

        //休眠1100ms为了让代码执行到wait();
        Thread.sleep(1100);
        log.info("第一个线程的状态:{}", thread.getState());
    }

    @Override
    public void run() {
        synchronize();
    }

    private synchronized void synchronize() {
        try {
            Thread.sleep(1000);
            wait();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            e.printStackTrace();
        }
    }
}
结果:
17:46:19.601 [main] INFO com.diamondshine.Thread.ThreadClass - 第一个线程的状态:TIMED_WAITING
17:46:19.608 [main] INFO com.diamondshine.Thread.ThreadClass - 第二个线程的状态:BLOCKED
17:46:20.708 [main] INFO com.diamondshine.Thread.ThreadClass - 第一个线程的状态:WAITING

验证结果符合预期,当调用sleep(),线程处于Timed_Waiting,因为Synchronized进入阻塞,处于Blocked,调用wait(),处于waiting状态。

原文地址:https://www.cnblogs.com/huigelaile/p/11721305.html

时间: 2024-10-08 04:02:03

并发和多线程(三)--线程的生命周期/状态的相关文章

Java多线程 2 线程的生命周期和状态控制

一.线程的生命周期 线程状态转换图: 1.新建状态 用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态.处于新生状态的线程有自己的内存空间,通过调用start方法进入就绪状态(runnable). 注意:不能对已经启动的线程再次调用start()方法,否则会出现Java.lang.IllegalThreadStateException异常. 2.就绪状态 处于就绪状态的线程已经具备了运行条件,但还没有分配到CPU,处于线程就绪队列(尽管是采用队列形式,事实上,把它

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

前言 线程是操作系统中的一个概念,支持多线程的语言都是对OS中的线程进行了封装.要学好线程,就要搞清除它的生命周期,也就是生命周期各个节点的状态转换机制.不同的开发语言对操作系统中的线程进行了不同的封装,但是对于线程的声明周期这部分基本是相同的.下面先介绍通用的线程生命周期模型,然后详细介绍Java中的线程生命周期以及Java生命周期中各个状态是如何转换的. 通用的线程生命周期 上图为通用线程状态转换图(五态模型). 初始状态 线程被创建,但是还不允许分配CPU执行.这里的创建仅仅是指在编程语言

Java 多线程(三) 线程的生命周期及优先级

Java 多线程(三) 线程的生命周期及优先级 线程的生命周期 线程的生命周期:一个线程从创建到消亡的过程. 如下图,表示线程生命周期中的各个状态: 线程的生命周期可以分为四个状态: 1.创建状态: 当用new操作符创建一个新的线程对象时,该线程处于创建状态. 处于创建状态的线程只是一个空的线程对象,系统不为它分配资源. 2.可运行状态: 执行线程的start()方法将为线程分配必须的系统资源,安排其运行,并调用线程体——run()方法,这样就使得该线程处于可运行状态(Runnable). 这一

Java多线程——线程的生命周期和状态控制

一.线程的生命周期 线程状态转换图: 1.新建状态 用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态.处于新生状态的线程有自己的内存空间,通过调用start方法进入就绪状态(runnable). 注意:不能对已经启动的线程再次调用start()方法,否则会出现java.lang.IllegalThreadStateException异常. 2.就绪状态 处于就绪状态的线程已经具备了运行条件,但还没有分配到CPU,处于线程就绪队列(尽管是采用队列形式,事实上,把它

Java多线程(二)、线程的生命周期和状态控制(转)

Java多线程(二).线程的生命周期和状态控制 分类: javaSE综合知识点 2012-09-10 16:11 15937人阅读 评论(3) 收藏 举报 一.线程的生命周期 线程状态转换图: 1.新建状态 用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态.处于新生状态的线程有自己的内存空间,通过调用start方法进入就绪状态(runnable). 注意:不能对已经启动的线程再次调用start()方法,否则会出现java.lang.IllegalThreadSt

Java并发编程:线程的生命周期是个怎样的过程?

前言 在日常开发过程中,如果我们需要执行一些比较耗时的程序的话,一般来说都是开启一个新线程,把耗时的代码放在线程里,然后开启线程执行.但线程是会耗费系统资源的,如果有多个线程同时运行,互相之间抢占系统资源,那无疑会对系统造成极大的压力.所以,怎么操作线程,保证不影响整个应用功能是很重要的,而这就需要我们了解线程的生命周期了. 线程的生命周期 线程的生命周期有6种状态,分别是NEW(新建).RUNNABLE(可运行).BLOCKED(被阻塞). WAITING(等待).TIMED_WAITING(

Java多线程开发系列之三:线程这一辈子(线程的生命周期)

前文中已经提到了,关于多线程的基础知识和多线程的创建.但是如果想要很好的管理多线程,一定要对线程的生命周期有一个整体概念.本节即对线程的一生进行介绍,让大家对线程的各个时段的状态有一定了解. 线程的一生的状态过程 如下图: 线程会由出生 到运行  再到 死亡.在前文中曾经讲到过(寻找前文请点这里):java中各个线程是抢占式的:cpu一般不会为一个线程从出生一直服务到老,各个线程总是争抢的希望得到cpu的“青睐”.当某个线程发生阻塞时,那么cpu就会被其他线程迅速抢占.而当前阻塞的线程只能变为就

第18章 多线程----线程的生命周期

线程具有生命周期,其中包含7中状态,分别为:出生状态.就绪状态.运行状态.等待状态.休眠状态.阻塞状态.死忙状态. 1.线程的休眠 例如:在项目中创建SleepMethodTest类,该类继承了JFrame类,实现在窗体中自动画线段的功能,并且为线段设置颜色,颜色是随机产生的. import java.awt.*; import java.util.*; import javax.swing.*; public class SleepMethodTest extends JFrame { pri

Java 并发 线程的生命周期

Java 并发 线程的生命周期 @author ixenos 线程的生命周期 线程状态: a)     New 新建 b)     Runnable 可运行 c)     Running 运行 (调用getState()时显示为Runnable) d)     Blocked 阻塞 i.          I/O阻塞 (不释放锁) I/O操作完成解除阻塞,进入Runnable状态 ii.          同步阻塞(不释放锁) 运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会