线程的状态

Thread.State枚举类型中定义了线程的六种状态:NEWRUNNABLEBLOCKEDWAITINGTIMED_WAITINGTERMINATED

线程在某一时刻只能拥有一种状态,但是在线程的整个生命周期,线程的状态会发生变化。

  1. public enum State {
  2. NEW,
  3. RUNNABLE,
  4. BLOCKED,
  5. WAITING,
  6. TIMED_WAITING,
  7. TERMINATED;
  8. }

各状态的说明

NEW

NEW状态是线程已经被创建,但还没调用start()。此时的线程是不可运行的,CPU将不会为其分配时间。

RUNNABLE

当新创建的线程调用了start(),线程便进入了RUNNABLE状态。

RUNNABLE状态是指可以获得CPU运行时间的状态,如果线程在此状态下,线程有两种子状态,一种是等待CPU时间,另一种是获得了CPU时间在执行代码。

BLOCKED

BLOCKED状态是线程无法获取对象锁时的状态。此状态下线程会阻塞,当线程成功获取到锁,线程将切换为RUNNABLE状态。

BLOCKED状态无法获得CPU运行时间。

WAITING

WAITING状态是指是指线程在执行过程中,主动出让自己CPU运行时间,让其他线程先执行,自己等待其它线程的特定操作后再恢复执行。

TIMED_WAITING

TIMED_WAITINGWAITING状态相似,TIMED_WAITING增加了时间限制,其实没有外部信号,在等待时间超时后,线程也会恢复。

TERMINATED

TERMINATED是线程的终止态,当线程执行完自己的任务,或在执行任务中发生了异常,线程都会进入TERMINATED,表示线程已经到了生命周期的末尾。

下图是关于线程间各状态切换的过程及发生状态切换的一些条件。

操作 操作前线程状态 操作后线程状态 是否出让CPU时间 是否需要先持有对象锁 是否释放对象锁
new Thread() NEW
Thread.start() NEW RUNNABLE
synchronized能得到对象锁 RUNNABLE RUNNABLE
synchronized无法得到对象锁 RUNNABLE BLOCKED
Thread.join() RUNNABLE WAITING
Thread.join(t) RUNNABLE TIMED_WAITING
Thread.sleep(t) RUNNABLE TIMED_WAITING
Object.wait() RUNNABLE WAITING
Object.wait(t) RUNNABLE TIMED_WAITING
Object.notify() / Object.notifyAll() RUNNABLE RUNNABLE
Lock.lock() RUNNABLE WAITING
Lock.tryLock(t) RUNNABLE TIMED_WAITING
LockSupport.park() RUNNABLE WAITING
LockSupport.parkNanos(t)/LockSupport.parkUntil(t) RUNNABLE TIMED_WAITING
执行结束/执行异常 RUNNABLE TERMINATED

以下是一些测试代码,可以运行下清晰的了解到状态。

各状态切换测试:

  1. public class ThreadStateTest {
  2. public static void main(String[] args){
  3. threadStateNew();
  4. workingThread();
  5. threadStateTerminate();
  6. threadBlockedByLock();
  7. threadBlockedBySynchronized();
  8. threadSleep();
  9. threadWait();
  10. threadTimedWait();
  11. }
  12. private static void threadStateNew(){
  13. System.out.println("--------------------------");
  14. System.out.print("Never Start Thread State:");
  15. Thread thread = new Thread(()->{
  16. }, "Thread Never Start");
  17. //print NEW
  18. System.out.println(thread.getState());
  19. System.out.println("--------------------------");
  20. }
  21. private static void workingThread(){
  22. System.out.println("--------------------------");
  23. Thread thread = new Thread(()->{
  24. for(int i=0; i<100; i++){
  25. doSomeElse();
  26. }
  27. });
  28. thread.start();
  29. doSomeElse();
  30. //print RUNNABLE
  31. System.out.println("Working Thread State:" + thread.getState());
  32. System.out.println("--------------------------");
  33. }
  34. private static void threadStateTerminate(){
  35. System.out.println("--------------------------");
  36. System.out.print("Finish Job Thread State:");
  37. Thread thread = new Thread(()->{
  38. }, "Thread Finish Job");
  39. thread.start();
  40. try {
  41. //Main Thread Will Wait util this thread finished job
  42. thread.join();
  43. } catch (InterruptedException e) {
  44. e.printStackTrace();
  45. }
  46. //print TERMINATED
  47. System.out.println(thread.getState());
  48. System.out.println("--------------------------");
  49. }
  50. private static void threadBlockedByLock(){
  51. System.out.println("--------------------------");
  52. System.out.print("Thread State Blocked By Lock:");
  53. ReentrantLock lock = new ReentrantLock();
  54. Thread thread = new Thread(()->{
  55. lock.lock();
  56. }, "Blocked Thread");
  57. lock.lock();
  58. thread.start();
  59. doSomeElse();
  60. //print WAITING
  61. System.out.println(thread.getState());
  62. lock.unlock();
  63. System.out.println("--------------------------");
  64. }
  65. private static void threadBlockedBySynchronized(){
  66. System.out.println("--------------------------");
  67. System.out.print("Thread Blocked By Synchronized:");
  68. Thread thread = new Thread(()->{
  69. synchronized (ThreadStateTest.class){
  70. }
  71. }, "Blocked by Synchronized Thread");
  72. synchronized (ThreadStateTest.class){
  73. thread.start();
  74. doSomeElse();
  75. //print BLOCKED
  76. System.out.println(thread.getState());
  77. }
  78. System.out.println("--------------------------");
  79. }
  80. private static void threadSleep(){
  81. System.out.println("--------------------------");
  82. System.out.print("Sleeping Thread:");
  83. Thread thread = new Thread(()->{
  84. try {
  85. Thread.sleep(10000);
  86. } catch (InterruptedException e) {
  87. e.printStackTrace();
  88. }
  89. }, "Thread sleep");
  90. thread.start();
  91. doSomeElse();
  92. //print TIMED_WAITING
  93. System.out.println(thread.getState());
  94. System.out.println("--------------------------");
  95. }
  96. private static void threadWait(){
  97. System.out.println("--------------------------");
  98. System.out.print("Thread Waiting:");
  99. Object lock = new Object();
  100. Thread threadA = new Thread(()->{
  101. synchronized (lock){
  102. try {
  103. lock.wait();
  104. for(int i=0; i<100; i++){
  105. doSomeElse();
  106. }
  107. } catch (InterruptedException e) {
  108. e.printStackTrace();
  109. }
  110. }
  111. }, "Thread Waiting");
  112. Thread threadB = new Thread(()->{
  113. synchronized (lock){
  114. //print WAITING
  115. System.out.println("Before Notify, Thread A State:" + threadA.getState());
  116. lock.notify();
  117. //print BLOCKED
  118. System.out.println("After Notify, Thread A State:" + threadA.getState());
  119. }
  120. });
  121. threadA.start();
  122. doSomeElse();
  123. threadB.start();
  124. try {
  125. threadB.join();
  126. } catch (InterruptedException e) {
  127. e.printStackTrace();
  128. }
  129. //print RUNNABLE
  130. System.out.println("After Thread B finish job, Thread A State:" + threadA.getState());
  131. System.out.println("--------------------------");
  132. }
  133. private static void threadTimedWait(){
  134. System.out.println("--------------------------");
  135. System.out.print("Thread Waiting:");
  136. Object lock = new Object();
  137. Thread threadA = new Thread(()->{
  138. synchronized (lock){
  139. try {
  140. lock.wait(1000);
  141. for(int i=0; i<100; i++){
  142. doSomeElse();
  143. }
  144. } catch (InterruptedException e) {
  145. e.printStackTrace();
  146. }
  147. }
  148. }, "Thread Waiting");
  149. Thread threadB = new Thread(()->{
  150. synchronized (lock){
  151. //print TIMED_WAITING
  152. System.out.println("Before Notify, Thread A State:" + threadA.getState());
  153. lock.notify();
  154. //print BLOCKED
  155. System.out.println("After Notify, Thread A State:" + threadA.getState());
  156. }
  157. });
  158. threadA.start();
  159. doSomeElse();
  160. threadB.start();
  161. try {
  162. threadB.join();
  163. } catch (InterruptedException e) {
  164. e.printStackTrace();
  165. }
  166. //print RUNNABLE
  167. System.out.println("After Thread B finish job, Thread A State:" + threadA.getState());
  168. System.out.println("--------------------------");
  169. }
  170. /**
  171. * take some times, let the thread get cpu time
  172. */
  173. private static void doSomeElse(){
  174. double meanless = 0d;
  175. for(int i=0; i<10000; i++){
  176. meanless += Math.random();
  177. }
  178. }
  179. }

CPU时间运行测试:

  1. public class ThreadCPUTimeTest {
  2. public static void main(String[] args) {
  3. testBlockedThreadCPUTime();
  4. }
  5. protected static void testBlockedThreadCPUTime() {
  6. Object lock = new Object();
  7. Thread threadA = new Thread(() -> {
  8. synchronized (lock) {
  9. doSomethingElse();
  10. }
  11. }, "ThreadA: Blocked because of synchronized");
  12. Thread threadB = new Thread(() -> {
  13. synchronized (lock) {
  14. try {
  15. threadA.start();
  16. Thread.sleep(100000);
  17. } catch (InterruptedException e) {
  18. e.printStackTrace();
  19. }
  20. }
  21. }, "ThreadB: With Monitor But Sleep");
  22. threadB.start();
  23. //Main Thread Executing Job
  24. for (int i = 0; i < 100000; i++) {
  25. doSomethingElse();
  26. }
  27. }
  28. private static void doSomethingElse() {
  29. double meanless = 0d;
  30. for (int i = 0; i < 10000; i++) {
  31. meanless += Math.random();
  32. }
  33. }
  34. }

用VISUALVM可以统计CPU时间:

详细代码可以GitHub

线程状态及各状态下与锁和CPU的关系的更多相关文章

  1. java 线程的几种状态

    java thread的运行周期中, 有几种状态, 在 java.lang.Thread.State 中有详细定义和说明: NEW 状态是指线程刚创建, 尚未启动 RUNNABLE 状态是线程正在正常 ...

  2. 在java中怎样实现多线程?线程的4种状态

    一.在java中怎样实现多线程? extends Thread implement Runnable 方法一:继承 Thread 类,覆盖方法 run(),我们在创建的 Thread 类的子类中重写 ...

  3. Java线程Thread的状态解析以及状态转换分析 多线程中篇(七)

    线程与操作系统中线程(进程)的概念同根同源,尽管千差万别. 操作系统中有状态以及状态的切换,Java线程中照样也有. State 在Thread类中有内部类 枚举State,用于抽象描述Java线程的 ...

  4. 透彻讲解,Java线程的6种状态及切换

    Java中线程的状态分为6种. 1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法.2. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running) ...

  5. Java线程的5种状态及切换(透彻讲解)-京东面试

    一.Thread的几个重要方法: 我们先了解一下Thread的几个重要方法. a.start()方法,开始执行该线程:b.stop()方法,强制结束该线程执行:c.join方法,等待该线程结束.d.s ...

  6. 【转】java 线程的几种状态

    java thread的运行周期中, 有几种状态, 在 java.lang.Thread.State 中有详细定义和说明: NEW 状态是指线程刚创建, 尚未启动 RUNNABLE 状态是线程正在正常 ...

  7. 线程的几种状态转换<转>

    线程在一定条件下,状态会发生变化.线程一共有以下几种状态: 1.新建状态(New):新创建了一个线程对象. 2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法. ...

  8. Java 多线程 线程的五种状态,线程 Sleep, Wait, notify, notifyAll

    一.先来看看Thread类里面都有哪几种状态,在Thread.class中可以找到这个枚举,它定义了线程的相关状态: public enum State { NEW, RUNNABLE, BLOCKE ...

  9. Java线程基础知识(状态、共享与协作)

    1.基础概念 CPU核心数和线程数的关系 核心数:线程数=1:1 ;使用了超线程技术后---> 1:2 CPU时间片轮转机制 又称RR调度,会导致上下文切换 什么是进程和线程 进程:程序运行资源 ...

随机推荐

  1. PTA | 1010 一元多项式求导 (25分)

    设计函数求一元多项式的导数.(注:xn(n为整数)的一阶导数为n*xn-1.) 输入格式: 以指数递降方式输入多项式非零项系数和指数(绝对值均为不超过1000的整数).数字间以空格分隔. 输出格式: ...

  2. 从String 聊源码解读

    @ 目录 源码实现 构造方法 equals 其他方法 常见面试题 你真的了解String吗?之前一篇博客写jvm时,就觉得String可以单独拎出来写一篇博客,毕竟几乎所有的面试都是以String开始 ...

  3. Ubuntu16.04安装Vmware Tools

    开启虚拟机 安装VMware Tools 在虚拟机名称上,右键>>安装VMware Tools 此时,Ubuntu会提示已经插入光盘,并弹出文件管理页面. 此时我们打开终端查看分区挂载情况 ...

  4. django内置的分页功能

    django内置的分页功能 # 先导入需要查询的模型类 from game.models import Score # 导入内置的分页功能 from django.core.paginator imp ...

  5. 【Web】阿里icon图标webpack插件(webpack-qc-iconfont-plugin)详解

    webpack-qc-iconfont-plugin webpack-qc-iconfont-plugin是一个webpack插件,可以轻松地帮你将阿里icon的图标项目下载至本地 开发初衷 之前已经 ...

  6. 【python实现卷积神经网络】优化器的实现(SGD、Nesterov、Adagrad、Adadelta、RMSprop、Adam)

    代码来源:https://github.com/eriklindernoren/ML-From-Scratch 卷积神经网络中卷积层Conv2D(带stride.padding)的具体实现:https ...

  7. 聊一聊深拷贝和浅拷贝(JS)

    在 JS 中数据类型分为值类型和引用类型,对于值类型,变量中存放的是具体的值,而对于引用类型,变量中存放的是地址. 对于值类型: const a = 3; let b = a; b = 4; cons ...

  8. Linux c++ vim环境搭建系列(5)——vim使用

    5. 使用 5.1 快捷键及设置 5.1.1 光标移动 w : 正向移动到相邻单词的首字符 b : 逆向移动到相邻单词的首字符 e : 正向移动到相邻单词的尾字符 ge : 逆向移动到相邻单词的尾字符 ...

  9. 数据结构和算法(Golang实现)(16)常见数据结构-字典

    字典 我们翻阅书籍时,很多时候都要查找目录,然后定位到我们要的页数,比如我们查找某个英文单词时,会从英语字典里查看单词表目录,然后定位到词的那一页. 计算机中,也有这种需求. 一.字典 字典是存储键值 ...

  10. [算法总结]DFS(深度优先搜索)

    目录 一.关于DFS 1. 什么是DFS 2. DFS的搜索方式 二.DFS的具体实现 三.剪枝 1. 顺序性剪枝 2. 重复性剪枝 3. 可行性剪枝 4. 最优性剪枝 5. 记忆化剪枝 四.练习 一 ...