1、五种状态

这是从 操作系统 层面来描述的

  • 【初始状态】仅是在语言层面创建了线程对象,还未与操作系统线程关联

  • 【可运行状态】(就绪状态)指该线程已经被创建(与操作系统线程关联),可以由 CPU 调度执行

  • 【运行状态】指获取了 CPU 时间片运行中的状态

    • 当 CPU 时间片用完,会从【运行状态】转换至【可运行状态】,会导致线程的上下文切换

  • 【阻塞状态】

    • 如果调用了阻塞 API,如 BIO 读写文件,这时该线程实际不会用到 CPU,会导致线程上下文切换,进入【阻塞状态】

    • 等 BIO 操作完毕,会由操作系统唤醒阻塞的线程,转换至【可运行状态】

    • 与【可运行状态】的区别是,对【阻塞状态】的线程来说只要它们一直不唤醒,调度器就一直不会考虑调度它们

  • 【终止状态】表示线程已经执行完毕,生命周期已经结束,不会再转换为其它状态

2、六种状态

这是从 Java API 层面来描述的,根据 Thread.State 枚举,分为六种状态

  • NEW 线程刚被创建,但是还没有调用 start() 方法

  • RUNNABLE (RUNNING)当调用了 start() 方法之后,注意,Java API 层面的 RUNNABLE 状态涵盖了 操作系统 层面的【可运行状态】、【运行状态】和【阻塞状态】(由于 BIO 导致的线程阻塞,在 Java 里无法区分,仍然认为是可运行)

  • BLOCKEDWAITINGTIMED_WAITING 都是 Java API 层面对【阻塞状态】的细分,后面会在状态转换一节详述

  • TERMINATED 当线程代码运行结束

代码示例

@Slf4j(topic = "c.TestState")
public class TestState {
   public static void main(String[] args) throws IOException {
       Thread t1 = new Thread("t1") {
           @Override
           public void run() {
               log.debug("running...");
          }
      };  // 未start 所以日志未打印

       Thread t2 = new Thread("t2") {
           @Override
           public void run() {
               while(true) { // runnable

              }
          }
      };
       t2.start();

       Thread t3 = new Thread("t3") {
           @Override
           public void run() {
               log.debug("running...");
          }
      };
       t3.start();

       Thread t4 = new Thread("t4") {
           @Override
           public void run() {
               synchronized (TestState.class) {
                   try {
                       Thread.sleep(1000000); // timed_waiting
                  } catch (InterruptedException e) {
                       e.printStackTrace();
                  }
              }
          }
      };
       t4.start();

       Thread t5 = new Thread("t5") {
           @Override
           public void run() {
               try {
                   t2.join(); // waiting
              } catch (InterruptedException e) {
                   e.printStackTrace();
              }
          }
      };
       t5.start();

       Thread t6 = new Thread("t6") {
           @Override
           public void run() {
               synchronized (TestState.class) { // blocked
                   try {
                       Thread.sleep(1000000);
                  } catch (InterruptedException e) {
                       e.printStackTrace();
                  }
              }
          }
      };
       t6.start();

       try {
           Thread.sleep(500);
      } catch (InterruptedException e) {
           e.printStackTrace();
      }
       log.debug("t1 state {}", t1.getState());
       log.debug("t2 state {}", t2.getState());
       log.debug("t3 state {}", t3.getState());
       log.debug("t4 state {}", t4.getState());
       log.debug("t5 state {}", t5.getState());
       log.debug("t6 state {}", t6.getState());
       System.in.read();
  }
}

输出

Java并发(十一)----线程五种状态与六种状态的更多相关文章

  1. java线程五种状态

    java线程五种状态: 创建 -> 就绪 -> 运行 -> 销毁 创建 -> 就绪 -> 运行 -> 等待(缺少资源) -> 销毁 下图:各种状态转换

  2. [Java并发编程(五)] Java volatile 的实现原理

    [Java并发编程(五)] Java volatile 的实现原理 简介 在多线程并发编程中 synchronized 和 volatile 都扮演着重要的角色,volatile 是轻量级的 sync ...

  3. Java 并发 中断线程

    Java 并发 中断线程 @author ixenos 对Runnable.run()方法的三种处置情况 1.在Runnable.run()方法的中间中断它 2.等待该方法到达对cancel标志的测试 ...

  4. Java 并发编程 | 线程池详解

    原文: https://chenmingyu.top/concurrent-threadpool/ 线程池 线程池用来处理异步任务或者并发执行的任务 优点: 重复利用已创建的线程,减少创建和销毁线程造 ...

  5. java并发编程 线程基础

    java并发编程 线程基础 1. java中的多线程 java是天生多线程的,可以通过启动一个main方法,查看main方法启动的同时有多少线程同时启动 public class OnlyMain { ...

  6. Java并发——ThreadPoolExecutor线程池解析及Executor创建线程常见四种方式

    前言: 在刚学Java并发的时候基本上第一个demo都会写new Thread来创建线程.但是随着学的深入之后发现基本上都是使用线程池来直接获取线程.那么为什么会有这样的情况发生呢? new Thre ...

  7. java并发基础(五)--- 线程池的使用

    第8章介绍的是线程池的使用,直接进入正题. 一.线程饥饿死锁和饱和策略 1.线程饥饿死锁 在线程池中,如果任务依赖其他任务,那么可能产生死锁.举个极端的例子,在单线程的Executor中,如果一个任务 ...

  8. Java并发编程(五):Java线程安全性中的对象发布和逸出

    发布(Publish)和逸出(Escape)这两个概念倒是第一次听说,不过它在实际当中却十分常见,这和Java并发编程的线程安全性就很大的关系. 什么是发布?简单来说就是提供一个对象的引用给作用域之外 ...

  9. java并发:线程池、饱和策略、定制、扩展

    一.序言 当我们需要使用线程的时候,我们可以新建一个线程,然后显式调用线程的start()方法,这样实现起来非常简便,但在某些场景下存在缺陷:如果需要同时执行多个任务(即并发的线程数量很多),频繁地创 ...

  10. 【Java】设计模型-五种单例模型

    一. 什么是单例模式 只需要某个类同时保留一个对象,不希望有更多对象,此时,我们则应考虑单例模式的设计. 单例模式的主要作用是保证在Java程序中,某个类只有一个实例存在. 单例模式有很多好处,它能够 ...

随机推荐

  1. SHA-256 简介及 C# 和 js 实现【加密知多少系列】

    〇.简介 SHA-256 是 SHA-2 下细分出的一种算法.截止目前(2023-03)未出现"碰撞"案例,被视为是绝对安全的加密算法之一. SHA-2(安全散列算法 2:Secu ...

  2. jquery中判断复选框有没有被选上

    页面部分: <input type="checkbox" id="cbx" /><label for="cbx">点 ...

  3. Java中使用List的add方法后元素相同问题

    在写JavaWeb时,我在后端通过JDBC读取了数据后逐个使用List.add()方法添加元素并通过request方法传给jsp页面解析,但是添加以后出现了在列表里有n个(假设添加了n个元素)最后一个 ...

  4. 在Kubernetes(k8s)中部署 jenkins

    在Kubernetes(k8s)中部署 jenkins YAML配置文件 由于jenkins需要持久化存储,通过nfs动态供给pvc存储卷. 可以参考我之前的文档:https://cloud.tenc ...

  5. [数据库/MYSQL]#解决缺陷#设置Unique索引时:"[Err] 1071 - Specified key was too long; max key length is 767 bytes"

    1 问题复现 原表结构: CREATE TABLE `XX_TEMPERATURE` ( `FLOW_ID` int(11) NOT NULL COMMENT '独立的数据表或FTP唯一标识', -- ...

  6. Hugging News #0407: Google AI 的 Pix2Struct 来啦、开发者资源页面发布

    每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...

  7. MySQL之 InnoDB 内存结构

    从MySQL 5.5版本开始默认 使用InnoDB作为引擎,它擅长处理事务,具有自动崩溃恢复的特性,在日常开发中使用非常广泛 下面是官方的InnoDB引擎架构图,主要分为内存结构和磁盘结构两大部分. ...

  8. 四月七号java基础学习

    1.数据类型分为基本数据类型以及引用数据类型 基本数据类型有整型.浮点型.字符型.布尔型 引用数据类型有类.数组以及接口 2.常量的声明需要用关键字final来标识 3.JAVA语言的变量名称由数字, ...

  9. hadoop伪分布式集群的安装(不是单机版)

    准备工作 三台虚拟机,关闭防火墙,关闭selinux 查看防火状态 systemctl status firewalld 暂时关闭防火墙 systemctl stop firewalld 永久关闭防火 ...

  10. TiDB与MySQL的SQL差异及执行计划简析

    作者:京东零售 肖勇 一. 前言导读 TiDB作为NewSQL,其在对MySQL(SQL92协议)的兼容上做了很多,MySQL作为当下使用较广的事务型数据库,在IT界尤其是互联网间使用广泛,那么对于开 ...