简单谈谈Java 中的线程的几种状态

当Java程序启动时,JVM会为主线程分配一个特殊的栈来执行代码。同时,程序可以创建若干个子线程以支持并发执行相应的任务。线程在执行过程中,可以出现以下几种状态:

新建状态(New)

当线程对象创建以后,该线程处于新建状态。此时线程对象已经在内存中了,但是还没有分配系统资源,没有被CPU选中去执行,也没有开始执行线程中的代码。因此,新建状态的线程在内存中的状态是一片混沌。

代码示例

public class NewThreadDemo {
    public static void main(String[] args) {
        Thread thread = new Thread();
        System.out.println("New Thread's State: " + thread.getState());
    }
}

就绪状态(Runnable)

在获得了CPU时间片之后,线程开始执行,此时线程进入就绪状态。在线程进入就绪状态后,它就有机会获得系统的CPU时间片,占用CPU资源执行代码。

代码示例

public class ReadyThreadDemo {
    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 5; i++) {
                    System.out.println(Thread.currentThread().getName() + " running");
                }
            }
        });
        System.out.println("Thread's State: " + thread.getState());
        thread.start();
        System.out.println("Thread's State: " + thread.getState());
    }
}

在上述示例中,“Thread's State: RUNNABLE”代表线程已经被启动,进入就绪状态。由于线程是并发执行的,因此,运行结果是不确定的。

运行状态(Running)

当就绪状态的线程获得CPU时间片,开始执行run()方法(或者是重新执行run()方法)之后,线程进入运行状态。此时,线程会执行它的任务代码。

代码示例

public class RunningThreadDemo {
    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 5; i++) {
                    System.out.println(Thread.currentThread().getName() + " running");
                }
            }
        });
        System.out.println("Thread's State: " + thread.getState());
        thread.start();
        while (thread.getState() != Thread.State.TERMINATED) {
            System.out.println("Thread's State: " + thread.getState());
        }
        System.out.println("Thread's State: " + thread.getState());
    }
}

在上述示例中,“Thread's State: RUNNING”代表线程正在运行。为了让线程运行一定的时间,我们使用了while循环来输出线程的状态,直到线程运行结束(TERMINATED)。

阻塞状态(Blocked)

线程在执行过程中,可能因为某些原因,比如等待输入输出、等待某个锁、休眠等,使CPU无法继续执行该线程。此时,线程就从运行状态进入了阻塞状态,等待相应的条件被满足后重新进入就绪状态以等待获取资源继续执行。

代码示例

public class BlockedThreadDemo {
    public static void main(String[] args) throws InterruptedException {
        final Object lock = new Object();
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock) {
                    System.out.println(Thread.currentThread().getName() + " acquired lock");
                    try {
                        System.out.println(Thread.currentThread().getName() + " waiting for lock...");
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + " released lock");
                }
            }
        });
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock) {
                    System.out.println(Thread.currentThread().getName() + " acquired lock");
                    try {
                        TimeUnit.SECONDS.sleep(3);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    lock.notify();
                    System.out.println(Thread.currentThread().getName() + " sent signal");
                }
                System.out.println(Thread.currentThread().getName() + " released lock");
            }
        });
        thread1.start();
        thread2.start();
        TimeUnit.SECONDS.sleep(1);
        System.out.println("Thread 1 State: " + thread1.getState());
        System.out.println("Thread 2 State: " + thread2.getState());
        TimeUnit.SECONDS.sleep(3);
        System.out.println("Thread 1 State: " + thread1.getState());
        System.out.println("Thread 2 State: " + thread2.getState());
    }
}

在上述示例中,线程thread1试图获得一个锁,但是该锁被线程thread2占用,因此,线程thread1将进入阻塞状态,等待线程thread2释放锁并发送信号唤醒它。

终止状态(Terminated)

线程执行完自己的任务后,自动结束执行,进入终止状态。此时,线程释放占用的资源,例如对象锁、IO资源等。终止状态的线程不可再次调用start()方法。

代码示例

public class TerminatedThreadDemo {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 5; i++) {
                    System.out.println(Thread.currentThread().getName() + " running");
                }
            }
        });
        System.out.println("Thread's State: " + thread.getState());
        thread.start();
        TimeUnit.SECONDS.sleep(3);
        System.out.println("Thread's State: " + thread.getState());
    }
}

在上述示例中,在线程执行完自己的任务之后,线程进入终止状态。由于终止状态的线程不可再次调用start()方法,因此,运行结果如下:

Thread's State: NEW
Thread's State: RUNNABLE
Thread-0 running
Thread-0 running
Thread-0 running
Thread-0 running
Thread-0 running
Thread's State: TERMINATED

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

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

相关文章

  • php中并发读写文件冲突的解决方案

    下面我将为您详细讲解PHP中并发读写文件冲突的解决方案。 1. 问题描述 在PHP应用程序中,我们通常需要进行文件的读写操作。然而,在多个请求同时访问同一个文件时,可能会出现并发读写文件的冲突问题。具体表现为,不同的请求同时对同一个文件进行写操作时,可能会出现数据覆盖的情况。为了避免这个问题,我们需要进行并发读写文件的冲突处理。 2. 解决方案 2.1. 使…

    多线程 2023年5月16日
    00
  • 简单了解Java多线程实现的四种方式

    我来为你详细讲解“简单了解Java多线程实现的四种方式”的攻略。 一、前言 在现代计算机领域,我们经常需要使用多线程程序来提高运算效率和并发处理速度。特别是在Java开发领域中,涉及多线程的应用几乎无处不在。因此,了解Java多线程的实现方式是非常重要的。 二、Java 多线程的实现方式 Java 多线程的实现方式主要有以下四种: 继承Thread类 实现R…

    多线程 2023年5月17日
    00
  • Tomcat使用线程池处理远程并发请求的方法

    下面我将提供完整的攻略,包括Tomcat使用线程池处理远程并发请求的原理、具体的实现方法以及两个示例说明。 1. 原理 Tomcat使用线程池处理远程并发请求的原理是:Tomcat在启动时会初始化一个线程池,用于处理客户端的请求。当有新的客户端请求到达时,Tomcat会从线程池中获取一个可用的线程来处理请求。如果线程池中所有线程都在忙碌状态,新的请求将会进入…

    多线程 2023年5月16日
    00
  • 基于redis乐观锁实现并发排队

    基于Redis乐观锁实现并发排队的攻略需要分为以下几步: 第一步:确定Redis存储设计 首先需要确定Redis存储设计,用于存储患者排队信息。可以考虑使用Redis Sorted Set,Set中的元素是待处理的患者排队信息,Sorted Set中的元素则是已处理的患者排队信息,Score则是时间戳用来排序,患者排队信息应该至少包含患者姓名、身份证号码、就…

    多线程 2023年5月16日
    00
  • c# winform多线程的小例子

    下面我将详细讲解如何实现一个基于C# WinForm的多线程小例子。本攻略将涵盖以下内容: 如何在C# WinForm项目中进行多线程编程; 如何在多线程中避免出现线程安全问题; 常用的多线程技术和编程方法。 1. 多线程编程基础 针对WinForm程序,我们通常会在UI线程中进行界面的绘制和操作,而在其他线程中进行一些比较耗时的操作,如读取文件、网络请求等…

    多线程 2023年5月17日
    00
  • Java多线程编程中的并发安全问题及解决方法

    Java多线程编程中的并发安全问题及解决方法 1. 并发安全问题 Java多线程编程在实现高并发、高性能的同时,也带来了一些潜在的并发安全问题,如: 线程间数据竞争 线程间操作顺序问题 线程安全性问题 接下来,我们详细讲解这些问题。 1.1 线程间数据竞争 当多个线程同时对一个共享的变量进行读写时,会出现线程间数据竞争问题。因为操作系统的线程调度是不可控的,…

    多线程 2023年5月16日
    00
  • Java并发系列之AbstractQueuedSynchronizer源码分析(条件队列)

    下面是详细讲解“Java并发系列之AbstractQueuedSynchronizer源码分析(条件队列)”的完整攻略。 1. 前言 本文主要分析 Java 并发包中最重要的实现类之一:AbstractQueuedSynchronizer,并以此为引子学习 Java 中的锁与并发编程。具体地,我们会讨论以下几个问题: AbstractQueuedSynchr…

    多线程 2023年5月17日
    00
  • Java多线程编程综合案例详解

    下面是针对“Java多线程编程综合案例详解”的完整攻略,帮助读者深入了解Java多线程编程。 Java多线程编程综合案例详解 简介 多线程编程是Java开发中非常重要的一个部分,能有效地提高程序的运行效率。本文介绍一个基于Java多线程技术的综合案例,主要包括案例的背景、功能、流程等内容。 案例背景 假设有一个银行系统,要求支持并发访问,其中主要包含两个功能…

    多线程 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部