详解Java的线程状态

yizhihongxing

Java中的线程可以处于不同的状态,包括NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING和TERMINATED。了解这些状态及其转换对于优化并发程序和解决并发问题非常重要。以下是详解Java的线程状态的完整攻略:

线程的状态

  • NEW:创建一个线程对象,但是还没有调用start方法时,线程对象的状态是NEW。
  • RUNNABLE:一旦调用start方法,线程就进入RUNNABLE状态。在这个状态下,线程可以被CPU分配时间片,执行任务。但是,需要注意的是,RUNNABLE状态下的线程可能没有获取到锁,也可能在等待某个资源,等待时间片分配,或者被其他线程阻塞。
  • BLOCKED:当线程在等待获得锁、等待I/O事件完成等原因时,就会进入BLOCKED状态。在这个状态下,线程会永远等待当前需要的资源被释放。
  • WAITING:当线程在等待某个其他线程通知被通知之前,可以处于WAITING状态。在这个状态下,线程是无限期等待,直到获取到通知。
  • TIMED_WAITING:当线程在等待某个其他线程通知被通知之前,可以处于TIMED_WAITING状态,这个状态下线程等待一定的时间,并且会在等待超时或者获取到通知之前被唤醒。
  • TERMINATED:线程运行结束后,进入TERMINATED状态。

线程状态转换

Java线程的状态可以通过调用以下方法实现:

  • Thread.sleep(long millis)
  • Object.wait()
  • Object.wait(long timeout)
  • Thread.yield()
  • LockSupport.park()
  • LockSupport.unpark(Thread thread)

示例1

public class ThreadStatusDemo {

    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            synchronized (ThreadStatusDemo.class) {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        System.out.println("t1 state: " + t1.getState()); // NEW
        t1.start(); 
        System.out.println("t1 state: " + t1.getState()); // RUNNABLE
        synchronized (ThreadStatusDemo.class) {
            System.out.println("t1 state: " + t1.getState()); // BLOCKED
        }
        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("t1 state: " + t1.getState()); // TERMINATED
    }
}

在这个示例中,线程t1开始于NEW状态,实际上它仅被创建,没有开始运行。调用start方法后,它进入了RUNNABLE状态,准备运行。在synchronized块中获得锁的代码中,t1将进入BLOCKED状态。几秒钟后,线程结束并进入TERMINATED状态。

示例2

public class ThreadStatusDemo2 {

    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread t2 = new Thread(() -> {
            synchronized (ThreadStatusDemo2.class) {
                try {
                    ThreadStatusDemo2.class.wait(); // 等待被通知
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        t1.start();
        t2.start();

        System.out.println("t1: " + t1.getState()); // RUNNABLE
        System.out.println("t2: " + t2.getState()); // BLOCKED

        try {
            Thread.sleep(3000); // 等待t1和t2都得到时间片执行
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("t1: " + t1.getState()); // TERMINATED
        synchronized (ThreadStatusDemo2.class) {
            ThreadStatusDemo2.class.notify(); // 通知t2
        }
        System.out.println("t2: " + t2.getState()); // TERMINATED
    }
}

在这个示例中,线程t1被创建并启动后,进入RUNNABLE状态,t2在synchronized块中等待调用notify或notifyAll方法,进入了WAITING状态。注意,使用wait方法需要获取该对象的监视器(即锁)。几秒钟后,t1结束并进入TERMINATED状态。接着,t2被通知并结束进入TERMINATED状态。

以上是详解Java的线程状态的完整攻略,理解线程状态及其转换过程是学习Java中并发编程的重要一步。

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

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

相关文章

  • Java中JDBC的使用教程详解

    Java中JDBC的使用教程详解 JDBC(Java Database Connectivity)是Java语言操作数据库的标准规范。本文将详细讲解Java中JDBC的使用教程,包括开发环境搭建、JDBC连接MySQL数据库、CRUD操作、事务管理等内容。 开发环境搭建 在使用JDBC之前,需要安装Java开发环境和MySQL数据库,并将MySQL JDBC…

    Java 2023年5月19日
    00
  • SpringMVC @GetMapping注解路径冲突问题解决

    在 SpringMVC 中,我们可以使用 @GetMapping 注解来处理 GET 请求。但是,有时候我们会遇到 @GetMapping 注解路径冲突的问题,本文将详细讲解这个问题的原因和解决方法,并提供两个示例说明。 1. 原因分析 在 SpringMVC 中,@GetMapping 注解用于处理 GET 请求,并指定请求的 URL 路径。如果多个 @G…

    Java 2023年5月18日
    00
  • set_include_path和get_include_path使用及注意事项

    set_include_path和get_include_path是PHP语言中用于设置和获取当前PHP文件包含路径的函数。 set_include_path函数 set_include_path函数用于设置当前PHP文件的包含路径。其语法如下: set_include_path ( string $new_include_path ): string|fa…

    Java 2023年6月15日
    00
  • SpringBoot+MybatisPlus+Mysql+JSP实战

    以下是关于SpringBoot+MybatisPlus+Mysql+JSP实战的完整攻略,内容包括环境搭建、数据库操作、页面渲染等: 环境搭建 安装JDK、Maven等开发环境。 创建一个SpringBoot项目,可以使用Spring Initializr或者IDEA等工具快速创建。 在项目的pom.xml文件中添加mybatis-plus和mysql依赖,…

    Java 2023年5月20日
    00
  • SpringBoot后端进行数据校验JSR303的使用详解

    下面是关于“SpringBoot后端进行数据校验JSR303的使用详解”的完整攻略。 一、什么是JSR303校验 JSR303是Java Bean Validation规范的一部分,用于数据验证,可以用于校验数据的正确性,比如校验输入的参数是否符合要求等。在SpringBoot应用中,可以方便地使用JSR303进行数据校验。 二、如何在SpringBoot中…

    Java 2023年5月20日
    00
  • Java 关键字static详解及实例代码

    Java关键字static详解及实例代码 什么是Java的关键字static Java的关键字static用于声明类、方法和变量,它可以用来标识一个类、方法和变量是否为静态的。 当我们把一个成员变量或成员方法定义为静态时,它可以被所有对象所共享,无需实例化对象就可以直接访问它们。而非静态的成员变量和成员方法必须通过实例化后才能进行访问。 Java关键字sta…

    Java 2023年5月30日
    00
  • idea2020导入spring5.1的源码详细教程

    下面是“idea2020导入spring5.1的源码详细教程”的完整攻略: 1. 下载Spring5.1源码 访问Spring的官网,找到Spring Framework 5.1的下载链接,下载压缩包并解压到本地任意目录。 2. 导入源码到IDEA 打开IDEA,点击“Open”或者“Import Project”,选择Spring源码所在的目录,导入项目。…

    Java 2023年5月31日
    00
  • SpringBoot分页的实现与long型id精度丢失问题的解决方案介绍

    针对SpringBoot分页的实现与long型id精度丢失问题的解决方案,我提供以下完整攻略: SpringBoot分页的实现 SpringBoot中分页的实现可以通过Pageable和Page进行操作。 1、Pageable Pageable是一个接口,我们可以通过PageRequest类来实例化这个接口。 Pageable pageable = Page…

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