Java线程的6种状态及切换教程

Java线程的6种状态及切换教程

Java是一种多线程编程语言,线程作为Java应用程序的基本执行单元,线程状态经常改变。正因为Java线程状态的改变,在多线程程序中使用线程,需要了解线程的6种状态及状态转换。本文将通过以下几个方面详细讲解Java线程的6种状态及状态转换的教程。

Java线程的6种状态

Java线程共有6种状态,分别是:

  • NEW(新建):线程被创建但尚未开始执行的状态。
  • RUNNABLE(就绪):线程执行所需的所有资源已准备就绪,线程等待调度执行的状态。
  • BLOCKED(阻塞):线程正在等待获取锁对象,此时其他线程获取到锁对象,并且线程的等待时间未到,线程会处于阻塞状态。
  • WAITING(等待):线程等待其他线程执行完成,进入等待状态。
  • TIMED_WAITING(定时等待):线程等待其他线程执行完成在指定时间内,定时等待状态。
  • TERMINATED(终止):线程执行完成或被中断结束的状态。

Java线程状态的转换

不同状态的线程可以相互转换。Java线程状态转换的条件如下:

  • 新建状态转换为可运行状态:调用线程start() 方法。
  • 就绪状态转换为运行状态:获得cpu时间片,开始执行代码。
  • 运行状态转换为就绪状态:当前线程的时间片用完或者线程sleep() 方法执行完毕。
  • 运行状态转换为阻塞状态:线程在synchronized()方法上未获得锁的情况下执行wait()或者别的类似方法时,线程就会进入阻塞状态。
  • 阻塞状态转换为就绪状态:线程获得锁并执行notify或者notifyAll()方法,线程返回就绪状态。
  • 运行状态和就绪状态线程转化为等待或者定时等待线程:执行wait()或sleep(time)或join(time)方法,进入等待或定时等待状态。
  • 等待或定时等待线程状态转换为就绪状态:等待或定时等待时间到,或唤醒该线程。

Java线程状态转换示例

示例1:线程转换为阻塞状态

public class Demo1 implements Runnable {
    public synchronized void run() {
        try {
            System.out.println(Thread.currentThread().getName()
                    + "占用资源,等待5s");
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws Exception{
        Demo1 demo1 = new Demo1();
        Thread t1 = new Thread(demo1, "线程1");
        Thread t2 = new Thread(demo1, "线程2");
        t1.start();
        Thread.sleep(1000);
        t2.start();
    }
}

运行结果:

线程1占用资源,等待5s
线程2占用资源,等待5s

我们会发现线程2没有在开始执行,而是正在等待资源,则在这个过程中线程2就处于阻塞状态了。

示例2:线程转换为等待状态

public class Demo2 {
    public static void main(String[] args) throws Exception{
        Object object = new Object();
        Thread t1 = new Thread(() -> {
            synchronized (object) {
                try {
                    System.out.println(Thread.currentThread().getName()
                            + " enter waiting state");
                    object.wait();
                    System.out.println(Thread.currentThread().getName()
                            + " restart execution");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "线程1");

        Thread t2 = new Thread(() -> {
            synchronized (object) {
                System.out.println(Thread.currentThread().getName() + " notify");
                object.notify();
            }
        }, "线程2");

        t1.start();
        Thread.sleep(1000L);
        t2.start();
    }
}

运行结果:

线程1 enter waiting state
线程2 notify
线程1 restart execution

如上,t1线程执行了object.wait()方法,导致线程进入等待状态,同时在t2线程中synchronized(object)代码块调用了object.notify()方法,唤醒了等待的线程t1,此时t1线程就处于就绪状态了。

总结

本文对Java线程的6种状态及状态转换进行了详细的讲解,并通过两个示例进行了演示,希望读者可以通过本文更深刻的理解Java的多线程编程思想。

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

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

相关文章

  • 什么是多线程安全问题?

    以下是关于多线程安全问题的完整使用攻略: 什么是多线程安全问题? 多线程安全问题是指在多线程环境下,由于多个线程同时访问共享资源而导的数据不一致、程序崩溃等问题。在多线程编程中,由于多个线程同时访问共享资源,可能会导致竞争、死锁、线程安全等问题。因此,在编写多线程程序时,需要注意多线程安全问题,保证程序的正确性和稳定性。 多线程安全问题的原因 多线程安全问题…

    Java 2023年5月12日
    00
  • Java获取接口所有实现类的方式详解

    关于Java获取接口所有实现类的方式,可以采用以下三种方法: 方法一:利用Java SPI机制 Java SPI(Service Provider Interface)即服务提供商接口,是Java标准类库中的一种服务提供发现机制。利用Java SPI机制,我们可以很容易地获取到某个接口的所有实现类。具体操作步骤如下: 定义接口MyService: java …

    Java 2023年5月19日
    00
  • 浅析Java中对象的创建与对象的数据类型转换

    这里是“浅析Java中对象的创建与对象的数据类型转换”的攻略。 1. 对象的创建 Java中的对象可以由new关键字创建,一个对象的创建需要以下步骤: 分配对象的内存空间:在堆内存中为新对象分配一片连续的空间,这个空间的大小由对象的数据类型和属性决定。 执行构造函数:在分配好内存空间之后,JVM会执行对象的构造函数,初始化对象的属性值等。 将对象的引用返回给…

    Java 2023年5月26日
    00
  • Spring Boot Starters简介及其优劣势

    SpringBootStarters简介及其优劣势 什么是SpringBoot Starters? SpringBoot Starters是一种快速构建Spring应用程序的方式,它旨在减少开发人员的配置工作量。SpringBoot提供了一系列官方的Starters,每个Starter都预配置了一个或多个Spring应用程序需要的依赖关系。 SpringBo…

    Java 2023年5月15日
    00
  • java后台如何利用Pattern提取所需字符详解

    下面就是关于“Java后台如何利用Pattern提取所需字符”的完整攻略: 1. 基本概念 在Java中,正则表达式的使用非常重要,而Pattern类就是Java中正则表达式的核心类,用于解析和匹配正则表达式。下面是Pattern类中最基本的方法: public static Pattern compile(String regex) public Matc…

    Java 2023年5月27日
    00
  • Spring Mvc下实现以文件流方式下载文件的方法示例

    下面是针对“Spring MVC下实现以文件流方式下载文件的方法示例”的完整攻略: 1. 需求分析 我们需要实现一个以文件流方式下载文件的功能,具体来说,就是用户在调用该接口时,能够将指定文件以文件流的形式返回浏览器端,让用户下载文件。 2. 实现步骤 2.1 定义接口 我们需要在Controller中定义一个接口来实现文件下载的功能,具体的代码如下: @R…

    Java 2023年6月15日
    00
  • java比较两个json文件的差异及说明

    Java比较两个JSON文件的差异及说明 在日常开发中,我们经常需要比较两个JSON文件之间的差异,以判断其中的数据是否有更新或者变化。Java提供了许多方式来实现JSON文件的比较,下面将详细介绍其中的常用方法。 一、JSON文件的读取 在对JSON文件进行比较之前,我们需要先读取这两个JSON文件中的数据。 // 读取JSON文件中的内容 public …

    Java 2023年5月26日
    00
  • 如何将SpringBoot项目打成 war 包并部署到Tomcat

    下面是将SpringBoot项目打成war包并部署到Tomcat的详细攻略。 1. 添加依赖 首先,我们需要在SpringBoot项目中添加Tomcat的依赖,以及修改pom.xml文件中的打包方式为war。 <!– 添加Tomcat的依赖 –> <dependency> <groupId>org.springfram…

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