一文详解Java线程的6种状态与生命周期

一文详解Java线程的6种状态与生命周期

线程生命周期

Java线程的生命周期可以分为6种不同的状态:
1. New(新建): 当线程对象被创建时,它处于新建状态,但还没有开始运行。
2. Runnable(可运行): 当调用start()方法时,线程进入可运行状态,等待被线程调度器分派时间片得以运行。
3. Blocked(阻塞): 线程被阻塞于某一个等待状态,如等待一个I/O操作的完成或等待获取一个锁。
4. Waiting(等待): 线程处于一个无限期的等待状态,直到线程被特定的notify()或notifyAll()方法唤醒。
5. Timed Waiting(超时等待): 线程等待一个指定的时间,在等待的时间到达之前可以通过notify()或notifyAll()方法唤醒。
6. Terminated(终止): 线程已经执行完毕或发生了一个异常而终止。

线程状态转换

Java线程的状态可以不断地改变,具体状态转换如下:

  1. New -> Runnable:当调用了线程对象的start()方法时,线程进入可运行状态,等待系统的线程调度器来调度该线程执行。
  2. Runnable -> Running:当线程被分配到CPU时间片后,线程开始执行run()方法,进入Running状态。
  3. Running -> Runnable:当线程在执行时,遇到了某个条件(如睡眠时间结束、I/O完成、wait()被notify()方法唤醒)无法继续执行时,线程自动切换成可运行状态。
  4. Running -> Blocked:当线程试图获取一个被其他线程持有的锁或者在等待某个输入/输出操作完成时,该线程会进入阻塞状态(Blocked)。
  5. Blocked -> Runnable:当线程持有锁的同时,马上就会调用synchronized方法/块(等待另外一个信号),该线程会进入阻塞状态(Blocked),等待另外一个信号。
  6. Running -> Waiting:线程执行wait()方法,处于 Waiting 状态,在被notify() 方法唤醒之前等待状态不会被改变。
  7. Waiting -> Runnable:线程被notify()方法唤醒,进入 Runnable 状态。
  8. Running -> Timed Waiting:线程执行sleep()方法或wait(long)方法,进入Timed Waiting状态,知道超时或被唤醒。
  9. Timed Waiting -> Runnable:线程等待超时或被唤醒,回归Runnable状态。
  10. 任何状态 -> Terminated:当线程执行完毕(run()方法完成),或者因为异常退出时,该线程被置于终止状态(Terminated)。

示例说明

示例1:线程阻塞

public class ThreadBlockTest {
    public static void main(String[] args) {
        Object lock = new Object();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized(lock) {
                    System.out.println("t1获取到锁,开始执行;");
                    try {
                        lock.wait();    // 使当前线程进入等待状态
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("t1被唤醒了,重新获取锁,继续执行");
                }
            }
        });
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized(lock) {
                    System.out.println("t2获取到锁,开始执行;");
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    lock.notify();  // 唤醒正在等待的线程
                    System.out.println("t2执行完成,释放锁");
                }
            }
        });
        t1.start();
        t2.start();
    }
}

以上代码中,我们创建了两个线程t1和t2,t1运行后,调用lock.wait()方法使自己处于阻塞状态,等待被唤醒。t2获得锁之后,先延时2秒钟,然后调用lock.notify()方法,唤醒正在等待的线程t1,使其从wait()方法阻塞的状态恢复到Runnable状态。

示例2:线程等待

public class ThreadWaitTest {
    public static void main(String[] args) {
        Object lock = new Object();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized(lock) {
                    System.out.println("t1获取到锁,开始执行");
                    try {
                        lock.wait(5000);    // 使当前线程进入等待状态,超时时间为5秒
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("t1被唤醒了,重新获取锁,继续执行");
                }
            }
        });
        t1.start();
    }
}

以上代码中,我们创建一个线程t1,在synchronized(lock)代码块中,调用lock.wait(5000)方法,使当前线程进入超时等待状态,等待5秒钟。5秒钟后,如果没有其他线程调用lock.notify()方法来唤醒当前线程,则t1从Timed Waiting状态转换为Runnable状态,继续执行。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:一文详解Java线程的6种状态与生命周期 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • Java日期时间字符串和毫秒相互转换的方法

    下面是详细讲解Java日期时间字符串和毫秒相互转换的方法的攻略。 一、Java日期时间字符串转毫秒 1.1 SimpleDateFormat类 在Java中,可以使用SimpleDateFormat类来完成日期时间字符串的转换。SimpleDateFormat是Java中日期时间格式化类的一个子类,它继承了DateFormat类,提供了非常方便的日期时间格式…

    Java 2023年5月20日
    00
  • 使用Spirng Boot Admin监控Spring Cloud应用项目

    下面是使用Spring Boot Admin监控Spring Cloud应用项目的完整攻略: 1. 安装和配置Spring Boot Admin 首先,需要在Spring Boot应用项目中添加相关依赖,以便于引入Spring Boot Admin。在pom.xml中加入以下内容: <dependency> <groupId>de.c…

    Java 2023年5月20日
    00
  • jsp 使用request为页面添加静态数据的实例

    下面是“jsp 使用request为页面添加静态数据的实例”的完整攻略: 1. 简介 在JSP页面中,我们可以使用 request 对象将静态数据传递到页面中,以便进行动态显示。 2. 实现过程 2.1 准备工作 首先,我们需要准备一个 JSP 页面,用来接收静态数据并进行展示。例如: <!DOCTYPE html> <html> &…

    Java 2023年6月15日
    00
  • 微信小程序登录状态java后台解密

    微信小程序登录状态 Java 后台解密,主要是通过解密过程,获取登录凭证和用户的唯一标识 openID,然后根据此信息进行业务操作或者用户信息获取。具体步骤如下: 获取前端传来的 code 前端获取登录凭证 code,然后通过接口传给后台,后台通过微信提供的接口获取 session_key 和 openid。具体代码如下: String url = &quo…

    Java 2023年5月23日
    00
  • 详解如何热更新线上的Java服务器代码

    热更新线上的Java服务器代码是一项非常重要的工作,它可以帮助优化服务器运维和开发流程,从而提升系统的稳定性和可靠性。下面是我总结的详解热更新Java服务器代码的攻略: 1. 什么是热更新 所谓热更新,是指在不停机的情况下,将Java服务器代码替换成新的代码,从而实现在线上更新代码的目的。相比传统的停机更新方式,热更新更加方便快捷,不会对用户造成影响和中断服…

    Java 2023年6月16日
    00
  • Java Arrays.AsList原理及用法实例

    Java Arrays.AsList 原理及用法实例 简介 Arrays.AsList() 是 Java 中的一个常见方法,主要用于将数组转换成List集合。在实际开发中,我们通常将数组转化为 List 后,便可以使用其提供的方法方便地对集合进行操作。 语法 Arrays.asList(T… a); 其中 T 表示传入参数类型,a 表示用于转化的数组对象…

    Java 2023年5月26日
    00
  • java实现简易飞机大战

    Java实现简易飞机大战攻略 项目背景 飞机大战是一款经典的射击类游戏,玩家所扮演的角色是一架飞机,在空中飞行并与敌人战斗,通过不断的击败敌人来提升分数。本文将详细讲解如何使用Java实现一个简易版的飞机大战游戏。 实现步骤 创建游戏窗口 使用Java Swing组件,通过继承JFrame类来创建一个游戏窗口。在窗口中添加画布,用于绘制游戏背景和各种游戏元素…

    Java 2023年5月23日
    00
  • java中lambda表达式简单用例

    接下来我将为您详细讲解Java中Lambda表达式的简单用例攻略。 Lambda表达式简介 Lambda表达式是Java SE 8中新增的一个功能。它是一种匿名函数,它可以看做一种简化的、更紧凑的匿名内部类的写法。Lambda表达式的目的是使得Java语言更加紧凑、更易于读写。 Lambda表达式的语法 Lambda表达式的语法如下: (parameter1…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部