Java线程状态及切换

程序猿欧文 2020-11-11 10:10:17
java 线程 切换 状态


Java线程状态及切换

一、什么是Java线程状态

在Java程序中,用于描述Java线程的六种状态:

  • 新建(NEW):当前线程,刚刚新建出来,尚未启动。
  • 运行(RUNNABLE):当前线程,处于竞争CPU时间分片或已经获得CPU时间片的状态。
  • 等待(WAITTING):当前线程,处于休眠,不参与CPU时间片竞争的状态。
  • 定时等待(TIMED_WAITTING):当前线程,处于定时休眠,暂时不参与CPU时间片竞争的状态。
  • 阻塞(BLOCKED):当前线程,处于阻塞,不参与CPU时间片竞争的状态。
  • 终止(TERMINATED):当前线程,处于最终停止的状态。

新建状态,只能进入运行状态。而终止状态无法再转为其他状态。

等待/定时等待与阻塞,差别就是后者需要一个事件信号(如其他线程放弃当前线程需要的排他锁),才可以进行状态切换。当然,强行关闭也是可以的。

Java线程的实现并不受JVM规范约束,故不同虚拟机的实现,往往不同。目前主流的HotSpot是将每个Java线程直接映射到一个操作系统的原生线程,从而由操作系统完成一系列的线程调度

二、哪里看Java线程状态

查看Java线程状态,主要存在三种方式:

  • java.lang.Thread.State下可以直接看到Java的六种线程状态
  • Java运行时,程序内部可以通过Thread.getState()获取目标线程状态
  • Java运行时,程序外部可以通过jstack等工具,查看线程状态

有关jstack等工具等使用,后续会有博客,专门阐述。

三、什么时候变换Java线程状态

Java线程状态的切换嘛。不啰嗦,直接上图。
在这里插入图片描述
这张图涵盖了Java线程状态切换的各类方法。相较网上一些图片,更为详尽一些。
如果有所遗漏,可以告诉我,我会及时填补上。

四、谁在使用Java线程状态

日常开发中,我们并不会直接与线程状态进行交互。
我们往往直接使用JDK包装好的工具,如JUC包下的各类工具等。

举个栗子

线程池中的应用

位置:com.sun.corba.se.impl.orbutil.threadpool.ThreadPoolImpl#close

 // Note that this method should not return until AFTER all threads have died. public void close() throws IOException { // Copy to avoid concurrent modification problems. List<WorkerThread> copy = null; synchronized (workersLock) { copy = new ArrayList<>(workers); } for (WorkerThread wt : copy) { wt.close(); while (wt.getState() != Thread.State.TERMINATED) { try { wt.join(); } catch (InterruptedException exc) { wrapper.interruptedJoinCallWhileClosingThreadPool(exc, wt, this); } } } threadGroup = null; }

实际查看JDK后发现,JDK中其实也没有辣么多的实例,并且大多数直接关联线程状态的,也是一些状态查看的东东。
这在文章开头就说,Java线程操作,是很底层的,甚至其实现都不包含在虚拟机规范中。
主流的HotSpot,也是直接将Java线程映射到系统线程,由系统进行一系列的线程调度处理。
所以,在JDK中,是直接对线程状态进行处理的部分是很少的。

五、为什么需要线程状态

1.为什么需要线程状态这一概念

这个问题,可以从两个角度来说明:生命周期与资源管理

  • 一方面,线程状态很好地刻画了线程的整个生命周期,对生命周期中不同阶段进行了有效划分。
  • 另一方面,资源是有限的,需求是无限的。所以需要将系统资源有意识地进行调度,合理利用比较优势,追求帕累托最优。

实现后者的,就是利用线程在生命周期的不同阶段这一天然属性带来的状态刻画,进行的分组。CPU调度只需要关注运行状态的线程。而阻塞,等待等线程,都有着属于自己的一套处理方式。最终获得资源(开发时对复杂性的应对,运行时对系统资源对消耗,应用者心智模型的成长等)的优化分配。

2.JDK中为什么需要定义Java线程状态

前文有说到,Java中很少直接使用到线程状态。那么为什么还要在JDK中定义Java的六种线程状态呢?
一方面,通过信息透明的方式,降低使用者使用时建立心智模型的成本。如,现在的我们可以通过打印日志,打断点,快速了解Java的各个线程状态,并清楚了解产生的原因。从而大大提高了我们对Java线程的认识,进而更为愉快地拥抱JUC包下诸如线程池等工具。
另一方面,通过可以直接应用的状态枚举,我们可以很好地对现有工具进行二次开发等。如我们可以通过扩展AQS,并在其中添加线程状态的校验,从而得到定制化的线程同步工具。

六、如何使用线程状态

使用的方式,我已经在上文说了:学习Java线程,定制线程相关工具开发。
这里给出一个有关线程学习的demo:

/** * @program: learning * @description: 用于确认线程状态问题 * @author: Jarry * @create: 2020-10-26 22:25 **/public class ThreadState { public static void main(String[] args) { threadStateTest();// threadStateTest2();// threadStateWithBlocked();// threadStateWithException();// threadStateWithSuspend(); } /** * 实践证明:Thread.suspend()与Thread.resume()不会改变线程状态 * 线程状态该是Waiting,就Waiting。该Timed_Waiting就Timed_Waiting * Thread.suspend()与Thread.resume()只是挂起目标线程(并且不会释放锁资源) */ private static void threadStateWithSuspend() { Thread thread1 = new Thread(() -> {// LockSupport.park(); LockSupport.parkNanos(2000000000); }); thread1.start(); printThreadState(thread1); LockSupport.parkNanos(500000000); printThreadState(thread1); thread1.suspend(); printThreadState(thread1); LockSupport.parkNanos(500000000); printThreadState(thread1); thread1.resume(); LockSupport.parkNanos(500000000); printThreadState(thread1);// LockSupport.unpark(thread1); } /** * 展现线程阻塞状态 */ private static void threadStateWithBlocked() { Runnable runnable = new Runnable() { @Override public void run() { synchronized (ThreadState.class) {// LockSupport.parkNanos(2000000000); LockSupport.park(); } } }; Thread thread1 = new Thread(runnable); Thread thread2 = new Thread(runnable); thread1.start(); LockSupport.parkNanos(500000000); thread2.start(); // 加上以下时间间隔,则结果:Runnable->Blocked // 推论:Thread.start()会将线程状态设置为Runnable,然后在遇到sync的锁,再切换为Blocked状态// LockSupport.parkNanos(500000000); printThreadState(thread2); LockSupport.parkNanos(500000000); printThreadState(thread2); LockSupport.parkNanos(500000000); LockSupport.unpark(thread1); LockSupport.unpark(thread2); } /** * 由.........
版权声明
本文为[程序猿欧文]所创,转载请带上原文链接,感谢
https://my.oschina.net/mikeowen/blog/4712143

  1. 【计算机网络 12(1),尚学堂马士兵Java视频教程
  2. 【程序猿历程,史上最全的Java面试题集锦在这里
  3. 【程序猿历程(1),Javaweb视频教程百度云
  4. Notes on MySQL 45 lectures (1-7)
  5. [computer network 12 (1), Shang Xuetang Ma soldier java video tutorial
  6. The most complete collection of Java interview questions in history is here
  7. [process of program ape (1), JavaWeb video tutorial, baidu cloud
  8. Notes on MySQL 45 lectures (1-7)
  9. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  10. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  11. 精进 Spring Boot 03:Spring Boot 的配置文件和配置管理,以及用三种方式读取配置文件
  12. Refined spring boot 03: spring boot configuration files and configuration management, and reading configuration files in three ways
  13. 【递归,Java传智播客笔记
  14. [recursion, Java intelligence podcast notes
  15. [adhere to painting for 386 days] the beginning of spring of 24 solar terms
  16. K8S系列第八篇(Service、EndPoints以及高可用kubeadm部署)
  17. K8s Series Part 8 (service, endpoints and high availability kubeadm deployment)
  18. 【重识 HTML (3),350道Java面试真题分享
  19. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  20. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  21. [re recognize HTML (3) and share 350 real Java interview questions
  22. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  23. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  24. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  25. RPC 1: how to develop RPC framework from scratch
  26. 造轮子系列之RPC 1:如何从零开始开发RPC框架
  27. RPC 1: how to develop RPC framework from scratch
  28. 一次性捋清楚吧,对乱糟糟的,Spring事务扩展机制
  29. 一文彻底弄懂如何选择抽象类还是接口,连续四年百度Java岗必问面试题
  30. Redis常用命令
  31. 一双拖鞋引发的血案,狂神说Java系列笔记
  32. 一、mysql基础安装
  33. 一位程序员的独白:尽管我一生坎坷,Java框架面试基础
  34. Clear it all at once. For the messy, spring transaction extension mechanism
  35. A thorough understanding of how to choose abstract classes or interfaces, baidu Java post must ask interview questions for four consecutive years
  36. Redis common commands
  37. A pair of slippers triggered the murder, crazy God said java series notes
  38. 1、 MySQL basic installation
  39. Monologue of a programmer: despite my ups and downs in my life, Java framework is the foundation of interview
  40. 【大厂面试】三面三问Spring循环依赖,请一定要把这篇看完(建议收藏)
  41. 一线互联网企业中,springboot入门项目
  42. 一篇文带你入门SSM框架Spring开发,帮你快速拿Offer
  43. 【面试资料】Java全集、微服务、大数据、数据结构与算法、机器学习知识最全总结,283页pdf
  44. 【leetcode刷题】24.数组中重复的数字——Java版
  45. 【leetcode刷题】23.对称二叉树——Java版
  46. 【leetcode刷题】22.二叉树的中序遍历——Java版
  47. 【leetcode刷题】21.三数之和——Java版
  48. 【leetcode刷题】20.最长回文子串——Java版
  49. 【leetcode刷题】19.回文链表——Java版
  50. 【leetcode刷题】18.反转链表——Java版
  51. 【leetcode刷题】17.相交链表——Java&python版
  52. 【leetcode刷题】16.环形链表——Java版
  53. 【leetcode刷题】15.汉明距离——Java版
  54. 【leetcode刷题】14.找到所有数组中消失的数字——Java版
  55. 【leetcode刷题】13.比特位计数——Java版
  56. oracle控制用户权限命令
  57. 三年Java开发,继阿里,鲁班二期Java架构师
  58. Oracle必须要启动的服务
  59. 万字长文!深入剖析HashMap,Java基础笔试题大全带答案
  60. 一问Kafka就心慌?我却凭着这份,图灵学院vip课程百度云