「技术分享」Java线程状态间的互相转换看这个就行了

wavefar 2021-04-08 11:42:20
java


Java中线程的状态分为6种。

1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法。

2. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统地称为“运行”。 线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。

3.阻塞(BLOCKED):表示线程阻塞于锁。

4.等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。

5.超时等待(TIMED_WAITING):该状态不同于WAITING,它可以在指定的时间后自行返回。

6. 终止(TERMINATED):表示该线程已经执行完毕。

线程的状态图

1. 初始状态

实现Runnable接口和继承Thread可以得到一个线程类,new一个实例出来,线程就进入了初始状态。

2.1. 就绪状态

就绪状态只是说你资格运行,调度程序没有挑选到你,你就永远是就绪状态。调用线程的start()方法,此线程进入就绪状态。当前线程sleep()方法结束,其他线程join()结束,等待用户输入完毕,某个线程拿到对象锁,这些线程也将进入就绪状态。当前线程时间片用完了,调用当前线程的yield()方法,当前线程进入就绪状态。锁池里的线程拿到对象锁后,进入就绪状态。

2.2.运行中状态

线程调度程序从可运行池中选择一个线程作为当前线程时线程所处的状态。这也是线程进入运行状态的唯一一种方式。

3. 阻塞状态

阻塞状态是线程阻塞在进入synchronized关键字修饰的方法或代码块(获取锁)时的状态。

4. 等待

处于这种状态的线程不会被分配CPU执行时间,它们要等待被显式地唤醒,否则会处于无限期等待的状态。

5. 超时等待

处于这种状态的线程不会被分配CPU执行时间,不过无须无限期等待被其他线程显示地唤醒,在达到一定时间后它们会自动唤醒。

6. 终止状态

当线程的run()方法完成时,或者主线程的main()方法完成时,我们就认为它终止了。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。线程一旦终止了,就不能复生。 在一个终止的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。

7.等待队列

调用obj的wait(), notify()方法前,必须获得obj锁,也就是必须写在synchronized(obj) 代码段内。 与等待队列相关的步骤和图

  1. 线程1获取对象A的锁,正在使用对象A。

  2. 线程1调用对象A的wait()方法。

  3. 线程1释放对象A的锁,并马上进入等待队列。

  4. 锁池里面的对象争抢对象A的锁。

  5. 线程5获得对象A的锁,进入synchronized块,使用对象A。

  6. 线程5调用对象A的notifyAll()方法,唤醒所有线程,所有线程进入同步队列。若线程5调用对象A的notify()方法,则唤醒一个线程,不知道会唤醒谁,被唤醒的那个线程进入同步队列。

  7. notifyAll()方法所在synchronized结束,线程5释放对象A的锁。

  8. 同步队列的线程争抢对象锁,但线程1什么时候能抢到就不知道了。

同步队列状态

当前线程想调用对象A的同步方法时,发现对象A的锁被别的线程占有,此时当前线程进入同步队列。简言之,同步队列里面放的都是想争夺对象锁的线程。

当一个线程1被另外一个线程2唤醒时,1线程进入同步队列,去争夺对象锁。同步队列是在同步的环境下才有的概念,一个对象对应一个同步队列。

几个方法的比较

Thread.sleep(long millis),一定是当前线程调用此方法,当前线程进入TIMED_WAITING状态,但不释放对象锁,millis后线程自动苏醒进入就绪状态。作用:给其它线程执行机会的最佳方式。

Thread.yield(),一定是当前线程调用此方法,当前线程放弃获取的CPU时间片,但不释放锁资源,由运行状态变为就绪状态,让OS再次选择线程。作用:让相同优先级的线程轮流执行,但并不保证一定会轮流执行。实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。Thread.yield()不会导致阻塞。该方法与sleep()类似,只是不能由用户指定暂停多长时间。

t.join()/t.join(long millis),当前线程里调用其它线程t的join方法,当前线程进入WAITING/TIMED_WAITING状态,当前线程不会释放已经持有的对象锁。线程t执行完毕或者millis时间到,当前线程进入就绪状态。

obj.wait(),当前线程调用对象的wait()方法,当前线程释放对象锁,进入等待队列。依靠notify()/notifyAll()唤醒或者wait(long timeout) timeout时间到自动唤醒。

obj.notify()唤醒在此对象监视器上等待的单个线程,选择是任意性的。notifyAll()唤醒在此对象监视器上等待的所有线程。

版权声明
本文为[wavefar]所创,转载请带上原文链接,感谢
https://my.oschina.net/u/1041902/blog/5011839

  1. 【TTS】传输表空间AIX asm -> linux asm
  2. 【TTS】传输表空间Linux asm -> AIX asm
  3. 【DB宝40】MySQL高可用管理工具Orchestrator简介及测试
  4. 【TTS】传输表空间Linux ->AIX 基于rman
  5. 一本关于HTTP的恋爱日记
  6. 【RocketMQ源码分析】深入消息存储(3)
  7. SpringCloud+Nacos实现服务配置中心(Hoxton版本)
  8. SICP:构造过程抽象--面向对象的解释
  9. 3w 字长文爆肝 Java 基础面试题!太顶了!!!
  10. Spring Cloud 升级之路 - 2020.0.x - 3. Undertow 的 accesslog 配置
  11. win10卸载mysql5.7
  12. MySQL 批量插入,如何不插入重复数据?
  13. k8s cronjob应用示例
  14. 非常规方法,轻松应对Oracle数据库危急异常
  15. Oracle hang 之sqlplus -prelim使用方法
  16. 如何全文搜索oracle官方文档
  17. Java student achievement management system course design, with source code!
  18. win10安装mysql8.0
  19. 手把手教你写一个spring IOC容器
  20. JAVA 中的异常(1)- 基本概念
  21. A love diary about http
  22. navicat连接win10 mysql8.0 报错2059
  23. [rocketmq source code analysis] in depth message storage (3)
  24. Implementation of service configuration center with spring cloud + Nacos (Hoxton version)
  25. SCIP: constructing data abstraction -- Explanation of queue and tree in data structure
  26. SCIP: abstraction of construction process -- object oriented explanation
  27. Using docker to build elasticsearch + kibana cluster
  28. What are the spring IOC features? I can't understand the source code!
  29. Spring cloud upgrade road - 2020.0. X - 3. Accesslog configuration of undertow
  30. 导致Oracle性能抖动的参数提醒
  31. 风险提醒之Oracle RAC高可用失效
  32. 小机上运行Oracle需要注意的进程调度bug
  33. Oracle内存过度消耗风险提醒
  34. Oracle SQL monitor
  35. 使用Bifrost实现Mysql的数据同步
  36. 揭秘Oracle数据库truncate原理
  37. 看了此文,Oracle SQL优化文章不必再看!
  38. Mybatis (3) map and fuzzy query expansion
  39. Kafka性能篇:为何这么“快”?
  40. 两个高频设计类面试题:如何设计HashMap和线程池
  41. [TTS] AIX - & gt; Linux -- Based on RMAN (real environment)
  42. 为什么学编程大部分人选Java编程语言?
  43. Redis 高可用篇:你管这叫 Sentinel 哨兵集群原理
  44. redis 为什么把简单的字符串设计成 SDS?
  45. [TTS] transfer table space AIX - & gt; Linux based on RMAN
  46. Linux 网卡数据收发过程分析
  47. Redis 高可用篇:你管这叫 Sentinel 哨兵集群原
  48. Redis 6.X Cluster 集群搭建
  49. [TTS] transfer table space AIX ASM - & gt; Linux ASM
  50. [TTS] transfer table space Linux ASM - & gt; AIX ASM
  51. 高性能通讯框架——Netty
  52. Brief introduction and test of orchestrator, a high availability management tool for MySQL
  53. [TTS] transfer table space Linux - & gt; AIX based on RMAN
  54. A love diary about http
  55. [rocketmq source code analysis] in depth message storage (3)
  56. Implementation of service configuration center with spring cloud + Nacos (Hoxton version)
  57. SiCp: abstraction of construction process -- object oriented explanation
  58. springboot网上点餐系统
  59. 【SPM】oracle如何固定执行计划
  60. 用好HugePage,告别Linux性能故障