深入体会线程状态的切换

news2024/9/23 1:20:55

✨✨hello,愿意点进来的小伙伴们,你们好呐!
🐻🐻系列专栏:【JavaEE初阶】
🐲🐲本篇内容:线程状态详解
🐯🐯作者简介:一名现大二的三非编程小白,日复一日,仍需努力。

Java线程的运行的生命周期可以分为6种不同的状态,在某一时刻线程只能处于其中一种状态

在这里插入图片描述

NEW : 初始状态,表示线程任务被构建,但是还没有调用start()方法.
RUNNABLE : 运行状态,在这个状态中,线程正在执行中或者线程在就绪队列中等待CPU的调度都为这个状态.
BLOCKED : 阻塞状态,表示线程阻塞干预.
WAITING : 等待状态,表示线程当前正在等待其他线程,比如调用 join(),wait()方法都会导致线程进入该状态
TIME_WAITING : 超时等待状态,这个状态不同意WAITING,这个状态也是等待,但是它会等待指定的时间后自己返回.
TERMINATED : 终止状态,表示当前线程已经执行完毕,即PCB释放了,但是线程对象的引用还在.

下面的图解会让我们更清晰的了解到线程创建,执行,等待,通知,销毁的一系列流程中的状态
在这里插入图片描述

💦💦💦接下来我来带大家体会线程的状态

    • NEW:
    • RUNNABLE:
    • WAITING:
    • TIMED_WAITING:
    • BLOCKED:
    • TERMINATED:

NEW:

public class ThreadDemo_NEW {
    public static void main(String[] args) {
        Thread thread = new Thread(() -> {
            System.out.println("演示NEW");
        });
        System.out.println(thread.getName() + " 状态为: " + thread.getState());
    }
}

在这里插入图片描述

在构建线程后没有启动线程前,线程处于NEW状态

RUNNABLE:

💨💨💨因为就绪状态与执行状态在Java中无法体现出来,都归为RUNNABLE状态,所以我就来展示RUNNABLE状态

public class ThreadDemo_RUNNABLE {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            System.out.println("演示RUNNABLE");
        });

        thread.start();
        System.out.println(thread.getName() + " 状态为: " + thread.getState());
        Thread.sleep(1000);
    }
}

在这里插入图片描述

在此时,线程已经启动所以状态为RUNNABLE

WAITING:

public class ThreadDemo_WAITING {
    public static void main(String[] args) throws InterruptedException {
        Object o = new Object();
        Thread thread = new Thread(() -> {
            System.out.println("演示WAITING");
            synchronized (o){
                try {
                    o.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        });
        thread.start();
        Thread.sleep(1000);
        System.out.println(thread.getName() + " 状态为: " + thread.getState());
    }
}

在这里插入图片描述

在这里插入图片描述

我们使用wait() 方法让Thread-0线程进入等待状态,这个时候没有指定等待时间,所以是死等

TIMED_WAITING:

public class ThreadDemo_TIMED_WAITING {
    public static void main(String[] args) throws InterruptedException {
        Object o = new Object();
        Thread thread = new Thread(() -> {
            System.out.println("演示TIMED_WAITING");
            synchronized (o){
                try {
                    o.wait(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

            }
        });
        thread.start();
        Thread.sleep(1000);
        System.out.println(thread.getName() + " 状态为: " + thread.getState());
    }
}

在这里插入图片描述

当指定等待时间后,线程就进入了超时等待的状态

BLOCKED:

public class ThreadDemo_BLOCKED {
    public static void main(String[] args) throws Exception {
        testBlocked();
    }
    public static void testBlocked() throws Exception {
        class Counter {
            int counter;
            public synchronized void increase() {
                counter++;
                try {
                    Thread.sleep(30000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }

        Counter c = new Counter();

        Thread t1 = new Thread(new Runnable() {
            public void run() {
                c.increase();
            }
        }, "t1线程");
        t1.start();

        Thread t2 = new Thread(new Runnable() {
            public void run() {
                c.increase();
            }
        }, "t2线程");
        t2.start();

        Thread.sleep(100); // 确保 t2 run已经得到执行
        System.out.println(t2.getName() + " 状态为: " + t2.getState());

    }
}

线程1 与线程2 都要争夺执行increase() 方法,最终导致的线程2阻塞

TERMINATED:

public class ThreadDemo_TERMINATED {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            System.out.println("演示TERMINATED");
        });
        thread.start();
        Thread.sleep(1000);
        System.out.println(thread.getName() + " 状态为: " + thread.getState());
    }
}

线程执行结束后,但是线程引用还有指向,未销毁,所以这个时候线程的状态就是终止状态

通过上面的展示,我们可以了解到线程自身的生命周期并不是固定的,而是通过代码执行在不同的状态下进行切换,对于线程的状态我们要很清楚的把握住.

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

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

相关文章

微机-------CPU与外设之间的数据传送方式

目录 一、无条件方式二、查询方式三、中断方式四、DMA方式一、无条件方式 外设要求:简单、数据变化缓慢。 外设被认为始终处于就绪状态。始终准备好数据或者始终准备好接收数据。 IN AL,数据端口 数据端口的地址通过CPU的地址总线送到地址译码器进行译码,同时该指令进行的是…

JAVASE(复习)——异常

所有的异常都是在java.lang包中的Throwable类中 一、Exception 和 Error 的区别 exception:程序本身发生的异常,可以捕获抛出异常,一般用try—catch—finally捕获。 error:发生在jvm层面的错误,程序无法处理。 二…

Git 如何调整 commit 的顺序

title: Git 如何调整 commit 的顺序 date: 2022-12-02 23:11 tags: [git] 〇、问题 使用哪条命令调整commit的顺序? git rebase -i 一、前言 今天测试了git hooks,产生了大量的commit,而后又进行了正常的commit,因此在这里是想要…

java——mybatis——Mybatis注解开发——@Update——修改数据

DAO接口: package com.sunxl.dao;import com.sunxl.pojo.User; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.SelectKey; import org.apache.ibatis.annotations.Update;impo…

SpringBoot+Thymeleaf上传头像并回显【表单提交】

参考文章:springbootthymeleaf实现图片上传并回显https://www.wanmait.com/note/shaowei/javaee/b3717a24fde24d3e89c47765a1a63214.html 一、新建SpringBoot项目 添加 spring web和 thymeleaf 的依赖 二、在templates新建页面 在页面中添加一个表单和一个文件上传…

8086,8088CPU管脚,奇偶地址体, ready信号,reset复位信号。规则字和非规则字

8086/8088均为40条引线,双列直插式封装,某些引线有多重功能,其功能转换有两种情况:一种是分时复用,一种是按组态定义。 用8088微处理器构成系统时,有两种不同的组态: 最小组态:808…

@AutoWired与@Resource

参考 : Qualifier - 搜索结果 - 知乎 Autowired和Resource的区别是什么? - 知乎 面试突击78:Autowired 和 Resource 有什么区别? - 掘金 目录 同一类型多个Bean报错问题 Resource注解 Resource的查找顺序 Resource注解实现依赖注入 Reso…

网课题库接口调用方法

网课题库接口调用方法 本平台优点: 多题库查题、独立后台、响应速度快、全网平台可查、功能最全! 1.想要给自己的公众号获得查题接口,只需要两步! 2.题库: 查题校园题库:查题校园题库后台(点…

QT对象树机制

Qt提供了对象树机制,能够自动、有效的组织和管理继承自QObject的Qt对象。 每个继承自QObject类的对象通过它的对象链表(QObjectList)来管理子类对象,当用户创建一个子对象时,其对象链表相应更新子类对象信息&#xff0…

Docker快速入门

容器Docker技术的演进 1.曾经部署应用,使用物理机部署,这可能会因为不同应用所依赖的版本号不同,不得已购买一套全新的机器,所以成本高、部署慢、资源浪费、难以迁移和拓展、可能会被限定硬件厂商。 2.之后引入了VMVare&#xff…

使用JPA和Hibernate查询分页

介绍 受到我最近给出的StackOverflow答案的启发,我决定是时候写一篇关于使用JPA和Hibernate时查询分页的文章了。 在本文中,您将了解如何使用查询分页来限制 JDBC大小并避免获取不必要的数据。ResultSet 如何在#Hibernate中使用查询分页来限制 JDBC 结…

pytorch深度学习实战lesson32

第三十二课 分布式训练 这个是15年的时候沐神在 CMU 装的一个小机群,里面有30台机器,各机群有大概60块 GPU , 60块 GPU一共花了三四万美金的样子,就是大概20万人民币。沐神表示最亏的是当年他们跑了太多深度学习的实验&#xff0c…

C语言-const char*,char const*,char *const理解

By: Ailson Jack Date: 2022.12.04 个人博客:http://www.only2fire.com/ 本文在我博客的地址是:http://www.only2fire.com/archives/150.html,排版更好,便于学习,也可以去我博客逛逛,兴许有你想要的内容呢。…

传奇外网开服教程-GEE传奇外网全套架设教程

版本不同,所用的引擎和配置也会不同,但是架设方法都是大同小异,今天明杰给大家分享GEE引擎的外网架设教程。​ 需要准备的东西:DBC200版本,补丁,客户端,服务器,备案域名&#xff0c…

【Typora】Typora 新手入门参数配置记录

目录 写在前面 更改图片大小 更换高亮背景 更换主题 写在前面 最近发现一款记笔记的软件——Typora,极简清爽的外观一下子就把我给吸引住了,它支持Markdown 的格式记录,可以让笔记更加有条理、美观,至于 typora 的一些写作语法…

Android入门第43天-Activity与Activity间的互相传值

介绍 今天的课程会比较好玩,我们在之前的Service篇章中看到了一种putExtras和getExtras来进行activity与service间的传值。而恰恰这种传值其实也是Android里的通用传值法。它同样可以适用在activity与activity间传值。 Android中的传值 传单个值 传多个值 具体我…

Spring注解(简便地使用 Bean )

目录 0. 前置工作 1. 将 Bean 存储到容器 2. 对象注入&#xff08;对象装配&#xff09;【从容器中将对象读取出来】 0. 前置工作 创建Maven项目后&#xff0c;在pom.xml中添加Spring所必须的依赖。 <dependencies><dependency><groupId>org.springframe…

22个每个程序员都应该知道的 Git 命令

在这篇文章中&#xff0c;我写了一个快速学习 git 命令的备忘单。它将包括开发人员每天使用的命令&#xff0c;如 git add、git commit、git pull、git fetch&#xff0c;并共享其他有用的 git 命令。 我一直使用Git的一些命令&#xff0c;今天这个列表清单&#xff0c;希望也…

LC-6256. 将节点分成尽可能多的组(二分图判定+BFS)【周赛322】

6256. 将节点分成尽可能多的组 难度困难8 给你一个正整数 n &#xff0c;表示一个 无向 图中的节点数目&#xff0c;节点编号从 1 到 n 。 同时给你一个二维整数数组 edges &#xff0c;其中 edges[i] [ai, bi] 表示节点 ai 和 bi 之间有一条 双向 边。注意给定的图可能是不…

第4章 R语言编程基础——数据整理与预处理

目录 4.1 经济/金融数据库 4.1.1 金融数据与数据库 4.1.2 国外金融数据库概况 4.1.3 国内金融数据库概况 4.1.4 数据的主要内容 4.2 数据格式 4.3 数据的导入 4.3.1 从控制台上输入数据 4.3.2 上市公司财务报表信息读取 4.4 [数据的预处理] 4.1.1 时序数据的预处理 4.1.2…