线程与操作系统中线程(进程)的概念同根同源,尽管千差万别。
操作系统中有状态以及状态的切换,Java线程中照样也有。

State

在Thread类中有内部类 枚举State,用于抽象描述Java线程的状态,共有6种不同的状态
详细定义如下:

public enum State {

/**

* 至今尚未启动的线程的状态。

*/

NEW,

/**

* 可运行线程的线程状态。

* 处于可运行状态的某一线程正在 Java 虚拟机中运行,但它可能正在等待操作系统中的其他资源,比如处理器。

*/

RUNNABLE,

/**

* 受阻塞并且正在等待监视器锁的某一线程的线程状态。

* 处于受阻塞状态的某一线程正在等待进入一个同步的块/方法的监视器锁,或者在调用 Object.wait 之后再次进入同步的块/方法。

*/

BLOCKED,

/**

* 某一等待线程的线程状态。

* 某一线程因为调用下列方法之一而处于等待状态:

* 不带超时值的 Object.wait

* 不带超时值的 Thread.join

* LockSupport.park

* 处于等待状态的线程正等待另一个线程,以执行特定操作。

* 例如,已经在某一对象上调用了 Object.wait() 的线程正等待另一个线程,以便在该对象上调用 Object.notify() 或 Object.notifyAll()。

* 已经调用了 Thread.join() 的线程正在等待指定线程终止。

*/

WAITING,

/**

* 具有指定等待时间的某一等待线程的线程状态。

* 某一线程因为调用以下带有指定正等待时间的方法之一而处于定时等待状态:

* Thread.sleep

* 带有超时值的 Object.wait

* 带有超时值的 Thread.join

* LockSupport.parkNanos

* LockSupport.parkUntil

*/

TIMED_WAITING,

/**

* 已终止线程的线程状态。线程已经结束执行。

*/

TERMINATED;

}

状态详解
 

NEW

当一个线程创建后,也就是new了一个Thread,那么这个Thread的state就是NEW
有且只有这种情况下,才为NEW,不会从任何状态转换而来
也就是说如果一个线程状态已经不再是NEW,那么他永远不可能再重新回到NEW的状态,这是一个起点
 
下面的示例中创建了一个线程myThread,并没有调用start方法

TERMINATED

当一个线程终止后,就进入状态TERMINATED
TERMINATED作为线程的终点,一旦进入TERMINATED状态,将不再能够转换为其他状态
 
下面的示例中,创建了一个线程myThread,并且调用start方法启动
然后主线程(当前线程)sleep 1秒(确保myThread肯定结束了),然后查看myThread的状态,很显然,此时已经进入终止状态
 
NEW和TERMINATED分别对应线程生命周期的起点和终点
对于NEW来说,一旦离开,就永远回不来了;
对于TERMINATED来说,一旦到达, 就永远回不去了;

RUNNABLE

RUNNABLE用于表示可运行状态
下面的代码在主线程中运行,运行过程中是RUNNABLE状态
API中有说到:“处于可运行状态的某一线程正在 Java 虚拟机中运行,但它可能正在等待操作系统中的其他资源,比如处理器。”
也就是说一个RUNNABLE并不是一定正在运行
如果我们将线程运行所有的资源与条件分为两种:CPU时间片以及除了时间片以外的所有其他;
一旦进入RUNNABLE状态,那么他肯定已经拥有了“除了时间片以外的所有其他资源”
 但是,是否正在被执行?这个不确定,还要看是否被分配了时间片
如果没有处理器资源(时间片)那么就是“准备妥当”状态,如果分配了处理器资源(时间片),那么就是“正在运行”状态。
所以RUNNABLE状态可以细分为两种状态:准备妥当(READY)RUNNING(正在运行)
但是,为什么没有将RUNNABLE细分?
很显然,对于开发者来说能够做到的就是“除了时间片以外的所有其他资源”,而对于操作系统处理器CPU时间片的调度,是完全没有能力操控的(yield也只是提示)
所以,从应用的角度看,也就只有RUNNABLE状态,一个RUNNABLE的线程,他随时可能在运行,也可能在等待调度。

等待状态

BLOCKED、WAITING、TIMED_WAITING三种状态相对前面的几种,相对稍微复杂一点,因为会涉及到各种切换
对照着汉字来说,这三者都有“等”的意思,但是却又不太相同
举几个例子感受一下
当你发现前方信号灯转变为红灯时,你停车等待;
当你经过斑马线时,正好有行人经过,你停车等待;
当售票窗口中午休息时,你原地等待;
这几种等待更多的是因为不可抗力,不得不等的一种场景,BLOCKED更接近这种等待;
对于临界资源的访问,需要互斥访问,Java中使用对象监视器作为锁,想要进入同步区域,就需要获得对应的监视器锁
如果获取不到,就需要等待,这就是BLOCKED状态;
 
要出门时,你老婆说我化个妆,你等我下;
买水果时,售货员说刚卖完了,师傅去仓库去取了,您稍等一下;
此时的等,是在等一件事情的发生,WAITING更接近这种等待;
虽然都是在等待,卡住不能动,还是等一等,还是有区别的;
TIMED_WAITING与WAITING就比较相似了,他们的区别,从汉语的角度理解类似“你等我两分钟和你等一会”的区别
等两分钟有时间,等一会儿不确定到底等待多大一会儿
再回到Java线程中,可以认为:
  • 如果一个线程在等待获取进入同步区域的监视器锁,那么是BLOCKED;
  • 如果线程调用了不带超时值的等待方法,比如 Object.wait,持续等待某件事情的发生,直到收到通知,那么是WAITING
  • 如果线程调用了比如带有超时值的等待方法,比如wait(long timeout),进行一定时间的等待,到到时间后将不再等待,那么是TIMED_WAITING

状态转换图

 
换一个角度理解,线程状态的切换
下图从前驱和后继的角度分析了线程状态的变化
以中间一列为中心

状态对比

既然操作系统中线程概念模型有状态切换,Java线程也有状态,他们有何异同?
如上图所示,操作系统中的进程、线程模型的状态
核心为就绪(ready)阻塞(waiting)执行(run)
而对于Java线程中
核心状态为RUNNABLE、BLOCKED、WAITING、TIMED_WAITING(项目中根本不会创建线程,会借助于线程池,所以NEW和TERMINATED非重点)
Java线程为操作系统原生线程的映射,状态上也是有所映射的
Runnable状态,则对应了操作系统中的就绪(ready)和执行(run)
TIMED_WAITING ,WAITING还是BLOCKED,对应的都是操作系统线程的阻塞(waiting)状态
需要注意的是:这些状态是虚拟机状态,它不反映任何操作系统的线程状态,可以查看State的注释

为什么状态没有对应?

我们之前在提及线程的实现时,就有说到用户级和内核支持的对比,内核支持的是依靠操作系统来调度的,1.2之后就是对操作系统线程的映射
所以,既然调度依赖的是操作系统,那么,操作系统底层的状态对于开发者来说就不是那么必要了,因为你并不能对他进行事无巨细的控制
JVM中的线程是操作系统底层线程的映射,既然是映射,可以认为是一个薄层封装
封装的目的是为了更好的符合Java多线程编程的模型,而不是要原模原样的去照搬
从这一点也能更好地理解,为什么RUNNABLE相当于READY和RUNNING,因为JVM本来就只能做到这一步,READY还是RUNNING,搞不了,那还提供这两个状态干什么呢?
所以记住:
JVM中的状态只是Java的多线程模型中的状态,并不反应任何操作系统的线程状态
JVM中的状态与底层操作系统中线程的状态也没有必要去映射

Java线程Thread的状态解析以及状态转换分析 多线程中篇(七)的更多相关文章

  1. Java内存模型JMM 高并发原子性可见性有序性简介 多线程中篇(十)

    JVM运行时内存结构回顾 在JVM相关的介绍中,有说到JAVA运行时的内存结构,简单回顾下 整体结构如下图所示,大致分为五大块 而对于方法区中的数据,是属于所有线程共享的数据结构 而对于虚拟机栈中数据 ...

  2. Java线程的周期及五种状态

    线程的生命周期及五种基本状态 关于Java中线程的生命周期,首先看一下下面这张较为经典的图: 上图中基本上囊括了Java中多线程各重要知识点.掌握了上图中的各知识点,Java中的多线程也就基本上掌握了 ...

  3. Java线程池源码解析

    线程池 假如没有线程池,当存在较多的并发任务的时候,每执行一次任务,系统就要创建一个线程,任务完成后进行销毁,一旦并发任务过多,频繁的创建和销毁线程将会大大降低系统的效率.线程池能够对线程进行统一的分 ...

  4. java 线程 Thread 使用介绍,包含wait(),notifyAll() 等函数使用介绍

    (原创,转载请说明出处!谢谢--http://www.cnblogs.com/linguanh/) 此文目的为了帮助大家较全面.通俗地了解线程 Thread 相关基础知识! 目录: --线程的创建: ...

  5. Java 线程池(ThreadPoolExecutor)原理解析

    在我们的开发中“池”的概念并不罕见,有数据库连接池.线程池.对象池.常量池等等.下面我们主要针对线程池来一步一步揭开线程池的面纱. 有关java线程技术文章还可以推荐阅读:<关于java多线程w ...

  6. TCP协议 状态解析和状态统计

    一.三次握手和四次挥手 1.建立连接(三次握手)   (1)服务器会处于listen状态,客户端发送一个带SYN标志的TCP报文到服务器.   (2)服务器端回应客户端的请求,这是三次握手中的第2个报 ...

  7. Java并发编程:Java线程池核心ThreadPoolExecutor的使用和原理分析

    目录 引出线程池 Executor框架 ThreadPoolExecutor详解 构造函数 重要的变量 线程池执行流程 任务队列workQueue 任务拒绝策略 线程池的关闭 ThreadPoolEx ...

  8. java 线程Thread 技术--线程状态与同步问题

    线程技术第三篇: 线程的状态: 1. 创建状态: 当用new 操作符创建一个新的线程对象时,该线程就处于创建状态,系统不为它分配资源 2.可运行状态:当线程调用start 方法将为线程分配必须的系统资 ...

  9. java 线程Thread 技术--volatile关键字

    java 语言中允许线程访问共享变量,为了保证共享变量能被准确和一致的更新,Java 语言提供了volatile 关键字,也就是我们所说的内存一致性: 问题抛出:(尝试去运行下面代码,以及将volat ...

随机推荐

  1. laravel-elasticsearch 全文搜索设置

    1.首先安装 jave环境 jdk 下载地址 ,我用的是最新版本的,有时版本要跟elasticsearch对应 2.安装elasticsearch 下载地址 3.安装Laravel scout 全文搜 ...

  2. Bulk API

    承接上文,使用Java High Level REST Client操作elasticsearch Bulk API 高级客户端提供了批量处理器以协助批量请求 Bulk Request BulkReq ...

  3. sublime No packages available for installation

    package control user-setting 中添加: "channels": [ "C:\\channel_v3.json" ], channel ...

  4. 十八、泛型 l 注解 l Servlet3.0 l 动态代理 l 类加载器基础加强

    l 泛型 l 注解 l Servlet3.0 l 动态代理 l 类加载器 泛型 1 回顾泛型类 泛型类:具有一个或多个泛型变量的类被称之为泛型类. public class A<T> { ...

  5. 使用 python 实现π的计算

    1.π的神奇 π是一个无数人追随的真正的神奇数字.我不是很清楚一个永远重复的无理数的迷人之处.在我看来,我乐于计算π,也就是计算π的值.因为π是一个无理数,它是无限的.这就意味着任何对π的计算都仅仅是 ...

  6. 链表加bfs求补图联通块

    https://oj.neu.edu.cn/problem/1387 给一个点数N <= 100000, 边 <= 1000000的无向图,求补图的联通块数,以及每个块包含的点数 由于点数 ...

  7. 深入理解JVM(七)——性能监控工具

    前言 工欲善其事必先利其器,性能优化和故障排查在我们大都数人眼里是件比较棘手的事情,一是需要具备一定的原理知识作为基础,二是需要掌握排查问题和解决问题的流程.方法.本文就将介绍利用性能监控工具,帮助开 ...

  8. 合适么?现在学ASP.NET Core入门编程……

    现在都快找不到ASP.NET的培训课程了. 知道我要开课做培训,有同学劝我:“憋讲那什么.NET,讲Java,现在这个火!”我说我Java不熟,“唉呀!C#转Java,分分钟的事!以飞哥你的经验,…… ...

  9. 浅析PHP正则表达式的利用技巧

    浅析PHP正则表达式的利用技巧 正则表达式是什么 正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串. 将匹配的子串替换 ...

  10. [Swift]LeetCode152. 乘积最大子序列 | Maximum Product Subarray

    Given an integer array nums, find the contiguous subarray within an array (containing at least one n ...