【多线程基础】Java线程的六种状态

news2024/11/22 18:22:19

Hi~!这里是奋斗的明志,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~
🌱🌱个人主页:奋斗的明志
🌱🌱所属专栏:Java多线程

在这里插入图片描述

📚本系列文章为个人学习笔记,在这里撰写成文一为巩固知识,二为展示我的学习过程及理解。文笔、排版拙劣,望见谅。

在这里插入图片描述

目录

  • 一、线程的状态
    • 1.观察线程的所有状态
    • 2.线程状态和状态转移的意义
  • 二、 等待一个线程 - join()
  • 三、获取当前线程引用
  • 四、休眠当前线程

一、线程的状态

  • 之前谈到的“进程的状态”,更准确的说,是“线程的状态”,或者叫做“PCB的状态”
  • Java 中,对于线程的状态,大概是分成 6 中不同的状态~~

1.观察线程的所有状态

public static void main(String[] args) {
        for (Thread.State state : Thread.State.values()){
            System.out.println(state);
        }
    }

在这里插入图片描述


  • NEW:Thread对象有了,还没调用start,系统内部的线程还未创建
public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            System.out.println("hello");
        });
        System.out.println("start之前的状态:" + t.getState());
        t.start();
        t.join();
        System.out.println("start之后的状态:" + t.getState());
    }

在这里插入图片描述


  • TERMINATED:线程已经终止了,内核中的线程已经销毁了,Thread还在

  • RUNNABLE:就绪状态(可运行状态)(指这个线程“随叫随到”,正在CPU上执行或者没在CPU上执行,随时可以调度到CPU上执行)

  • WAITING:死等进入的阻塞

public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            while (true){
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t.start();
        //死等版本的 join
        t.join();

    }

在这里插入图片描述


  • TIMED_WAITING:带有超时时间的等
public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            while (true){
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t.start();
        //带有超时时间版本的 join
        t.join(3600 * 1000);

    }

在这里插入图片描述


在这里插入图片描述


  • BLOCKED: 这几个都表示排队等着其他事情

2.线程状态和状态转移的意义

在这里插入图片描述


在这里插入图片描述


还是我们之前的例⼦:
刚把李四、王五找来,还是给他们在安排任务,没让他们行动起来,就是 NEW 状态;
当李四、王五开始去窗⼝排队,等待服务,就进入到 RUNNABLE 状态。该状态并不表示已经被银行工作人员开始接待,排在队伍中也是属于该状态,即可被服务的状态,是否开始服务,则看调度器的调度;
当李四、王五因为⼀些事情需要去忙,例如需要填写信息、回家取证件、发呆⼀会等等时,进⼊
BLOCKEDWATINGTIMED_WAITING 状态,⾄于这些状态的细分,我们以后再详解;
如果李四、王五已经忙完,为 TERMINATED 状态。
所以,之前我们学过的 isAlive() 方法,可以认为是处于不是 NEW 和 TERMINATED 的状态都是活着的。

观察 1: 关注 NEWRUNNABLETERMINATED 状态的转换

public static void main(String[] args) {
        Thread t = new Thread(() -> {
            for (int i = 0; i < 1000_0000; i++) {

            }
        },"李四");
        System.out.println(t.getName() + ":" + t.getState());
        t.start();
        while (t.isAlive()){
            System.out.println(t.getName() + ":" + t.getState());
        }
        System.out.println(t.getName() + ":" + t.getState());
    }

在这里插入图片描述


观察 2: 关注 WAITING BLOCKEDTIMED_WAITING 状态的转换

public static void main(String[] args) {
        final Object object = new Object();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (object){
                    while (true){
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            }
        },"t1");
        t1.start();
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (object){
                    System.out.println("hehe");
                }
            }
        },"t2");
        t2.start();
    }

在这里插入图片描述


在这里插入图片描述


使用 jconsole 可以看到 t1 的状态是 TIMED_WAITING , t2 的状态是 BLOCKED

  • 修改上面的代码, 把 t1 中的 sleep 换成 wait
public static void main(String[] args) {
        final Object object = new Object();
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (object){
                    while (true){
                        try {
                            object.wait();
                        } catch (InterruptedException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
            }
        },"t1");
        t1.start();
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (object){
                    System.out.println("hehe");
                }
            }
        },"t2");
        t2.start();
    }

在这里插入图片描述


使⽤ jconsole 可以看到 t1 的状态是 WAITING

结论:

  • BLOCKED 表示等待获取锁, WAITINGTIMED_WAITING 表示等待其他线程发来通知.
  • TIMED_WAITING 线程在等待唤醒,但设置了时限; WAITING 线程在无限等待唤醒

二、 等待一个线程 - join()

有时,我们需要等待⼀个线程完成它的⼯作后,才能进行自己的下⼀步⼯作。例如,张三只有等李四转账成功,才决定是否存钱,这时我们需要一个方法明确等待线程的结束。

方法说明
public void join等待线程结束
public void join(long millis)等待线程结束,最多等 millis 毫秒
public void join(long millis,int nanos)同理,更高精度
public static void main(String[] args) throws InterruptedException {
        Runnable target = () -> {
            for (int i = 0; i < 3; i++) {
                System.out.println(Thread.currentThread().getName()
                 + ":我还在工作!");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            System.out.println(Thread.currentThread().getName() + ":我结束了!");
        };
        Thread t1 = new Thread(target,"李四");
        Thread t2 = new Thread(target,"王五");
        System.out.println("先让李四开始工作");
        t1.start();
        t1.join();
        System.out.println("李四工作结束了,开始让王五开始工作");
        t2.start();
        t2.join();
        System.out.println("王五工作结束了");
    }

在这里插入图片描述


三、获取当前线程引用

方法说明
public static void currentThread()返回当前线程的引用

在这里插入图片描述

四、休眠当前线程

也是我们比较熟悉⼀组⽅法,有⼀点要记得,因为线程的调度是不可控的,所以,这个方法只能保证实际休眠时间是大于等于参数设置的休眠时间的。

public static void main(String[] args) throws InterruptedException {
        System.out.println("start:" + System.currentTimeMillis());
        Thread.sleep(3 * 1000);
        System.out.println("end:" + System.currentTimeMillis());

    }

在这里插入图片描述

这里有一定的误差

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2069514.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

重生奇迹MU 冲锋在前近战职业

刀光剑影&#xff0c;近战搏杀的乐趣是热爱近战职业的玩家享受最强体验。重生奇迹MU中有很多近战职业&#xff0c;每个职业都拥有独特的技能和玩法&#xff0c;在战斗中表现也各不相同。选择近战职业的玩家都是英勇者&#xff0c;敢于冲锋陷阵&#xff0c;迎击敌人&#xff0c;…

【CSP:202303-2】垦田计划(Java)

题目链接 202303-2 垦田计划 题目描述 求解思路 直接模拟&#xff1a;创建一个数组arr[]&#xff0c;a[i]用来记录将第i天缩短所需要的资源数。在读取数据的时候直接对数组进行初始化。maxTime表示资源优化之前需要花费的最大天数。需要注意&#xff1a;在进行优化遍历时&am…

秋招力扣Hot100刷题总结——滑动窗口

1. 无重复字符的最长子串&#xff08;手撕频率非常高&#xff09; 题目要求&#xff1a;给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的最长子串的长度。 代码及思路 使用一个hashmap维护已经出现过的字符遍历字符串&#xff0c;当字符已经存在时&#xff0c;根…

微服务实战系列之玩转Docker(十二)

前言 山一程&#xff0c;水一程&#xff0c;身向榆关那畔行&#xff0c;夜深千帐灯。——清纳兰性德 最近偶读纳兰的《长相思》经典之作&#xff0c;被这个“行军”场面震撼了。长长的队伍&#xff0c;跋山涉水&#xff0c;野宿一处。夜深人静的时候&#xff0c;突然激发了纳兰…

CSS3页面布局-三栏-固定宽度布局

布局的基本概念 多栏布局三种基本实现方案&#xff1a;固定宽度&#xff0c;流动&#xff0c;弹性。 固定宽度布局&#xff1a;大小不会随用户调整浏览器窗口大小。 一版960-1100,960常见&#xff0c;可以被3,4,5,6,8,10,12,16整除。 流动布局&#xff1a;大小会随用户调整…

芯片要火不要“热”!仿真技术助力芯片热设计

芯片散热仿真好比一场微观世界里的“清凉大作战”&#xff01; 想象一下&#xff0c;小小的芯片就像迷你城市&#xff0c;无数的电子如同居民在其中穿梭。当芯片高速运转&#xff0c;就像城市进入了狂欢&#xff0c;热闹非凡但也会产生大量的热量。 而芯片散热仿真用数字和算法…

OpenStack前置配置与安装

环境&#xff1a;CentOS8最小化安装 九大组件&#xff1a; Nova:提供计算资源&#xff0c;cpu、内存等 Glance:提供镜像&#xff08;查找&#xff09;能力&#xff0c;真正存放镜像的是后端Swift。 Swift:对象存储&#xff0c;可以用来存放镜像。还可以用来存储备份。 Cin…

java生成黄红封面

import java.awt.*; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.File; import javax.imageio.ImageIO;public class CoverGenerator {public static void generateCover(String name, String outputPath) {// A4纸的分辨率 (300 …

POJO、PO、DTO、VO、BO到底是什么?都如何使用?(基础概念+传输示意图+示例代码)带你一次玩转层出不穷的Object

文章目录 前言一、解释关系二、POJO、PO、DTO、VO、DAO、BO1.什么是POJO&#xff08;Plain Old Java Object&#xff09;2.什么是PO&#xff08;Persistent Object&#xff09;3.什么是DTO&#xff08;Data Transfer Object&#xff09;4.什么是VO&#xff08;View Object&…

缓冲区

原理 #include <stdio.h> #include <string.h> int main() { const char *msg0"hello printf\n"; const char *msg1"hello fwrite\n"; const char *msg2"hello write\n"; printf("%s", msg0); fwrite(msg1, strlen(msg0)…

MySQL 数据页详解

数据页是MySQL 中定义的的一个存储结构 数据页是保存数据行的容器 页的16KB的大小是MySQL的⼀个默认设置&#xff0c;可以适用于⼤多数场景&#xff0c;当然也可以根据自己的实际业务场景进行修改页的大小&#xff0c;通过系统变量 innodb_page_size 进行调整与查看&#xff…

可计量Agilent N5181A详情资料keysight N5182A模拟信号发生器

Keysight N5181A&#xff08;Agilent&#xff09;MXG RF 模拟信号发生器的功能和规格包括&#xff1a;信号特性&#xff1a; 100 kHz 至 1、3 或 6 GHz 1 GHz 时输出功率为 23 dBm -121 dBc/Hz&#xff08;典型值&#xff09;相位噪声&#xff08;1 GHz 和 20 kHz 偏移&…

程序员常用的十个PyCharm插件,学会工作都不用加班了!

安装方法 先来说说插件的安装方法&#xff0c;一点都不难。 选择顶部菜单栏的 PyCharm 选项&#xff0c;打开 Preferences &#xff0c;点击 plugins &#xff0c;在右侧的文本框中输入想要查看的插件名称&#xff0c;在下方就会罗列出已经安装的相关的插件。 找到我们所需要的…

虹猫ai推文软件官方

虹猫AI推文软件是一款由虹猫小队开发的人工智能推文工具。该软件通过训练深度学习模型&#xff0c;能够自动生成优质的推文内容&#xff0c;帮助用户快速撰写出吸引人的推文。 虹猫ai推文软件官方https://iimenvrieak.feishu.cn/docx/O0UedptjbonN4UxyEy7cPlZknYc 虹猫AI推文软…

在Windows下安装设置VirtualBox

文章目录 一、下载VirtualBox二、安装VirtualBox三、安装虚拟机 一、下载VirtualBox 下载地址 直链下载 二、安装VirtualBox 打开下载好的安装包&#xff0c;点击下一步 根据自己的需求选择安装功能&#xff0c;之后选择安装目录&#xff0c;完成后下一步 提前注意是否有…

棚子影院CMS程序PHP源码

01, 棚子影视是我现在最常用的一个看视频的网站&#xff0c;支持观看电影、国漫&#xff01;动漫&#xff0c;电视剧、综艺、记录片、香港剧等等。同时棚子影视支持手机&#xff0c;PC端在线观看&#xff0c;不用下载任何播放器&#xff0c;直接电脑或者手机打开网址就可以在线…

自动化脚本到LabVIEW转换

工业自动化领域中的专用脚本语言转换为LabVIEW时需要注意的问题 语法差异&#xff1a; 脚本语言特点&#xff1a; 工业自动化脚本语言通常具有特定的语法和结构&#xff0c;例如条件判断、循环控制、硬件指令等。这些语言直接面向硬件操作&#xff0c;语法简洁&#xff0c;适用…

Python编码系列—Python单元测试的艺术:深入探索unittest与pytest

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

[数据集][目标检测]考场行为作弊检测数据集VOC+YOLO格式4413张4类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;4413 标注数量(xml文件个数)&#xff1a;4413 标注数量(txt文件个数)&#xff1a;4413 标注…

LeetCode33

445.两数相加Ⅱ 给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数字都不会以零开头。 示例1&#xff1a; 输入&#xff1a;l1 [7,2,4,3…