Java线程状态

article/2025/8/27 10:00:57

线程跟人类一样拥有自己的生命周期,一条线程从创建到执行完毕的过程即是线程的生命周期,此过程可能在不同时刻处于不同的状态,线程状态正是这小节的主题,线程到底有多少种状态?不同状态之间是如何转化的?

对于线程的状态的分类并没有严格的规定,只要能正确表示状态即可,如图2-5-7-1,先看其中一种状态分类,一个线程从创建到死亡可能会经历若干个状态,但在任意一个时间点线程只能处于其中一种状态,总共包含五个状态:新建(new)、可运行(runnable)、运行(running)、非可运行(not runnable)、死亡(dead)。线程的状态的转化可以由程序控制,通过某些API可以达到转化效果,例如Thread类的start、stop、sleep、suspend、resume、wait、notify等方法(stop、suspend、resume等方法因为容易引起死锁问题而早已被弃用)。

图2-5-7-1

 

l   新建(new):一个线程被创建了但未被启动就处于新建状态,即在程序中使用new MyThread();创建的线程实例就处于此状态。

l   可运行(runnable):创建的线程实例调用start()方法后便进入可运行状态,处于此状态的线程并不是说一定处于运行状态,我们在上一节多线程调度策略了解到Java多线程使用的是抢占式调度,每个可运行线程轮着获取CPU时间片,可以虚拟想象成有一个可运行线程池,start()方法把线程放进可运行线程池中,CPU按一定规则一个个执行池里的线程。

l   运行(running):当可运行线程获取到CPU执行时间片即进去了运行状态。

l   非可运行(notrunnable):运行中的线程因某种原因暂时放弃CPU的使用权,可能是因为执行了挂起、睡眠或等待等操作,在执行I/O操作时由于外部设备速度远低于处理器速度也可能导致线程暂时放弃CPU使用权,在获取对象的同步锁过程中如果同步锁先被别的线程占用同样可能导致线程暂时放弃CPU。

l   死亡(dead):线程执行完run()方法实现的任务,或因为异常导致退出任务,线程进入死亡状态后将不可再转换成其他状态。

将非可运行(not runnable)状态继续细分,如图2-5-7-2,新建、可运行、运行、死亡四个状态的定义和转化与前面的一样,重点看非可运行状态引申出来的三个状态:阻塞(blocked)、同步锁(locked)、等待(waiting)。

l   阻塞(blocked):阻塞由阻塞事件触发,线程处于阻塞状态将放弃CPU的使用权,暂时停止运行。一般线程执行了sleep()、join()方法,或发出了I/O请求,线程就将处于阻塞状态,假如sleep()执行的睡眠结束、join()执行的等待中断超时、I/O请求结束,则将重新回到可执行状态,等待分配CPU。

l   同步锁(locked):假如一个线程准备调用一个同步方法,而同步方法对应的对象正被其他线程占用,此时线程就将进入同步锁状态。实际上,Java中的每个object对象都有一个monitor,此monitor负责对同步域在并发时的独占处理,即一个线程调用某对象的同步方法时,JVM将检测改对象的monitor是否已被占用,如果没有被占用,线程则得到monitor占有权,继续执行该对象的同步方法,否则线程将被扔进一个等待线程队列排队,直到monitor被释放后,所有等待的线程继续竞争monitor占有权,抢到monitor占有权后才进入可执行状态等待CPU的分配,才有资格执行同步方法。

l   等待(waiting):运行中的线程执行了wait()方法后就进入等待状态。一个对象执行了wait()方法同样将使线程进入该对象的等待线程队列,同时它还将释放对象锁,即放弃monitor的占有权。只有在其他线程中对该对象调用notify()、notifyAll()方法时才会唤醒等待线程队列中的线程,notify是随机唤醒等待队列中的一个线程,而nofityAll则是唤醒所有等待队列中的线程,所有线程被唤醒后将对该对象的monitor占有权竞争,获取到占有权的线程才能转化为可执行状态,等待分配CPU往下执行,其他线程则继续等待。

 

图2-5-7-2





点击订购作者书籍《Tomcat内核设计剖析》





http://chatgpt.dhexx.cn/article/qfL2ITIC.shtml

相关文章

java线程状态与操作系统线程状态的关系

清楚的理解和认知线程状态是java多线程的基础,多线程本质上其实就是管理多个线程的状态,以期在保证线程安全的情况下获得最佳的运行效率(发挥cpu的最佳效能) 首先列举几个容易混淆的线程状态问题文末进行解答: 1Java线…

Java 如何获取线程状态呢?

下文笔者讲述Java中获取线程状态的方法分享,如下所示: java线程状态的简介 Java中的线程整个生命周期中分为5种状态:1.新建状态(New):新建的线程都为此状态2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法该状态的线程在"可运行线程池"中,…

【线程】详解线程状态(到底是五种还是六种)

首先我们要知道,在传统(操作系统)的线程模型中线程被分为五种状态 在java线程中,线程被分为六种状态 传统线程模型(操作系统)中线程状态 线程的五种状态: 1.新建(new) 创…

Java线程状态RUNNABLE详解

Java虚拟机层面所暴露给我们的状态,与操作系统底层的线程状态是两个不同层面的事。具体而言,这里说的 Java 线程状态均来自于 Thread 类下的 State 这一内部枚举类中所定义的状态: 什么是 RUNNABLE? 直接看它的 Javadoc 中的说明…

Java多线程 - 线程状态

线程状态 五个状态:新生、就绪、运行、死亡、阻塞 停止线程 不推荐使用JDK提供的stop()、destroy()方法【已弃用】推荐线程自己停止建议用一个标志位进行终止变量,到flagfalse,则终止线程运行 public class StopDemo implements Runnab…

jstack线程状态分析

使用jstack pid命令可以查看JVM的线程状态,其中值得关注的线程状态有: 死锁,Deadlock(重点关注)执行中,Runnable等待资源,Waiting on condition(重点关注)等待获取监视器&#xff0…

多线程之线程状态

## 线程状态 五大状态 1.创建状态:Thread thread new Thread(); 线程对象一旦创建就进入了新生状态。 2.就绪状态:当调用start()方法时,进入就绪状态,但不代表立即调度执行(等待cpu调度)。 3.运行状态或同…

Java线程的6种状态及切换(透彻讲解)

Java中线程的状态分为6种。 1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法。 2. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。 线程对…

线程的5种状态详解

概念 1.初始状态(NEW):新创建了一个线程对象。 2.可运行状态(RUNNABLE):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu…

线程的五种状态

1.新建状态(New): 创建一个新的线程对象。 2.就绪状态(Runnable): 线程创建对象后,其他线程调用start()方法,该线程处于就绪状态,资源已经准备就绪,等待CPU资源。 3.…

线程的几种状态

目录 前言 一、线程是什么? 二、线程状态 1.新建状态(New) 2.就绪状态(Runnable) 3.运行状态(Running) 4.阻塞状态(Blocked) 5.等待状态/超时等待(Wa…

Java的6种线程状态以及线程状态的转换

详细介绍了Java线程的6中状态,以及状态之间的转换。 文章目录 1 线程状态(生命周期)1.1 源码中的状态1.2 状态解释 2 线程状态转换2.1 进入等待/超时等待2.1.1 进入等待状态2.1.1.1 wait方法的介绍2.1.1.2 join方法的介绍 2.1.2 进入超时等待2.1.2.1 sleep方法的介绍…

Lombok 的 @Builder 的使用,默认值的设置,修改属性值

1,简单使用 2,属性默认值的设置问题 3,修改属性值 1,简单使用 他这个Builder注解,相比之前的编辑器自动生成的getter setter的优点在哪呢? 看下面的使用例子 package com.lxk.lombok;import com.lxk.m…

POJO属性定义包装类型还是基本类型

举个例子, private Boolean aaa;private boolean bbb;Boolean类型的变量会设置默认值为null,而boolean类型的变量会设置默认值为false。 也就是说,包装类型的默认值都是null,而基本数据类型的默认值是一个固定值,(boo…

MybatisPlus自动填充公共字段及特定类型属性设置默认值

前言 MybatisPlus是一个 MyBatis的增强工具,集成了mybatis和hibernate各自的优点,所以很受一些企业的喜爱。目前我们公司就在使用,确实特别好用。本文重点介绍自动填充公共字段及特定字段类型设置默认值的方法。 之前写过一篇关于JPA和mybat…

map的value默认值问题

关于map的value的默认值问题 结论&#xff1a; bool ----默认值为-------> false; int/double... ----默认值为-------> 0; string ----默认值为-------> "";#include<bits/stdc.h> #include<unordered_map>…

JPA生成表 给列加默认值 以及columnDefinition 失效的问题

做项目的时候 持久层使用jpa jpa的一些设置可以在application.yml 中实现 比如每次启动项目的时候 根据类自动创建表 控制台显示sql语句 创建一些表的时候 我们希望设置默认的值 比如创建一张student表 Data Entity EntityListeners(AuditingEntityListener.class) publi…

Spring MVC 实战:响应字段默认值设置

前言 到今天为止&#xff0c;相信大家开发 Web 项目应该都是前后端分离了吧&#xff1f;前后端分离中一般会使用 json 作为前后端的数据交换格式。json 中可以包含数值、字符串、json 对象、数组等等。 由于 json 可以转换为 JavaScript 对象&#xff0c;取对象的字段时需要保…

Java 中 Boolean 和 boolean的默认值和修改默认值

默认值 boolean 是 Java 的基本数据类型&#xff0c;默认值是false&#xff1b; Boolean 是 Java 的一个类&#xff0c;默认值是 null 使用推荐 根据阿里巴巴开发手册&#xff0c;在字段中推荐使用Boolean作为布尔类型的数据类型使用。 那么&#xff0c;如果需要修改Boolean的…

两个栈实现一个队列| 两个队列实现一个栈

#include "stack.h" typedef struct ISQueue {Stack s1;//入栈Stack s2;//出栈 &#xff0c;如果栈s2为空&#xff0c;则将s1中保存的数据导入s1 }TSQueue,*PTSQueue; void Init_Queue(PTSQueue pq);#include "TwoStack_to_queue.h" #include<stdio.h&g…