一、线程的5种状态

众所周知,Java的线程状态有5种,分别对应上图中五种不同颜色,下面对这5种状态及状态间的转化做相应的解释:

1. 初始化状态:新建一个线程对象

2. 可运行状态:其他线程调用了该线程对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权

3. 运行状态:可运行状态的线程获得了cpu 时间片(timeslice),执行程序代码

4. 阻塞状态:线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程再次进入可运行状态,才有机会转到运行状态。如图所示,会有三种不同类型的阻塞状态:

  • 等待阻塞:运行中的线程执行wait()方法,线程会进入等待队列中。等待notify()、notifyAll()或interrupt()对其唤醒或中断
  • 同步阻塞:运行中的线程执行在获取同步锁(注:只有synchronized这种方式的锁(monitor锁)才会让线程出现BLOCKED状态,等待ReentrantLock则不会)时,若该锁已被其他线程占用,线程则会进入锁池队列。等待获取到锁
  • 其他阻塞:运行的线程执行sleep()、join(),或触发了I/O请求,该该线程被置为阻塞状态。当sleep()状态超时、join()等待线程终止或超时、I/O处理完成,线程会重新进入可运行状态。

5. 死亡状态:线程执行完或因异常退出run()方法,线程生命周期结束

看完上面的配图和简介,可能会有人对阻塞状态的几种情况有些疑问,下面我们就一点一点解开她的小裙子 图中同样都是Blocked状态,等待队列和锁池是什么鬼?

等待队列和锁池都和wait()、notify()、synchronized有关,wait()和notify()又必须由对象调用且必须写在synchronized同步代码块内。

  1. 等待队列(等待被唤醒):对应等待阻塞。调用obj的wait()方法,则进入等待队列
  2. 锁池(等待抢锁):对应同步阻塞。

a)当前running线程调用对象obj的同步方法时,发现锁被其他线程持有,则直接进入锁池。

b)当前等待队列中阻塞的线程A,等待被线程B唤醒,唤醒后并非直接进去runnable状态,而是进入线程A所对应的锁池中,等待抢到锁。

下图直观描绘了running->等待队列->锁池->runnable间的状态流转,帮助大家理解。

怎么样,有没有通透很多?啊!还是有些小迷糊。好,那我们下面从jdk源码中对线程状态的描述进行分析

二、Thread.State枚举类中的BLOCKED、WAITING、TIMED_WAITING

我们打开Jdk源码中Thread类,会发现里面有定义State的枚举,枚举中有:NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED。由于线程中的初始化和死亡状态很短,我们不用太关心,runnable状态暂无歧义。我们只针对BLOCKED、WAITING、TIMED_WAITING三种可能混淆的状态进行分析

首先,上源码

/*** Thread state for a thread blocked waiting for a monitor lock.* A thread in the blocked state is waiting for a monitor lock* to enter a synchronized block/method or* reenter a synchronized block/method after calling* {@link Object#wait() Object.wait}.*/BLOCKED,// 受阻塞并且正在等待monitor锁的某一线程的线程状态。/*** Thread state for a waiting thread.* A thread is in the waiting state due to calling one of the* following methods:* <ul>*   <li>{@link Object#wait() Object.wait} with no timeout</li>*   <li>{@link #join() Thread.join} with no timeout</li>*   <li>{@link LockSupport#park() LockSupport.park}</li>* </ul>** <p>A thread in the waiting state is waiting for another thread to* perform a particular action.** For example, a thread that has called <tt>Object.wait()</tt>* on an object is waiting for another thread to call* <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on* that object. A thread that has called <tt>Thread.join()</tt>* is waiting for a specified thread to terminate.*/WAITING,// 某一等待线程的线程状态。/*** Thread state for a waiting thread with a specified waiting time.* A thread is in the timed waiting state due to calling one of* the following methods with a specified positive waiting time:* <ul>*   <li>{@link #sleep Thread.sleep}</li>*   <li>{@link Object#wait(long) Object.wait} with timeout</li>*   <li>{@link #join(long) Thread.join} with timeout</li>*   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>*   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>* </ul>*/TIMED_WAITING,// 具有指定等待时间的某一等待线程的线程状态

  1. BLOCKED场景:某一线程在等待monitor lock,比如在等待执行synchronized代码块/方法,这不就相当于进入了我们的锁池阻塞状态吗!;或在synchronized块/方法中循环调用obj的wait()方法,也就是线程在等待进入临界区。
  2. WAITING场景:某一线程因为调用下列方法之一而处于等待状态:
  • 不带超时值的 Object.wait
  • 不带超时值的 Thread.join
  • LockSupport.park 分析:既有可能进入等待队列,也有可能进入其他阻塞的阻塞状态

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

  • Thread.sleep(long millis)
  • 带有超时值的 Object.wait
  • 带有超时值的 Thread.join
  • LockSupport.parkNanos
  • LockSupport.parkUntil 分析:既有可能进入等待队列,也有可能进入其他阻塞的阻塞状态。和WAITING区别在于是否指定时间

结合实际编程经验,及工作中所遇到的情形,仔细回味一下上面两个模块的内容,可能就会恍然大悟。

三、并发编程中常用的几个jdk中的api的理解,可能面试常问哦

  1. Thread.sleep(long millis) 静态方法。当前线程调用此方法,使当前线程进入阻塞状态(其他阻塞),但不释放任何锁资源,一定时间后线程自动进入runnable状态。给其它线程执行机会的最佳方式
  2. obj.wait()或obj.wait(long timeout) 当前线程调用某对象的wait()方法,当前线程释放对象锁(wait一定在synchronized代码块/方法中,故一定得到了锁,才进来的此方法),进入阻塞状态(等待队列)。等待notify或wait设置的timeout到期,方可进入另外一个阻塞状态(锁池)。
  3. t.join()或t.join(long millis) 非静态方法。当前线程A执行过程中,调用B线程的join方法,使当前线程进入阻塞状态(其他阻塞),但不释放对象锁,等待B线程执行完后或一定时间millis后,A线程进入runnable状态。
  4. Thread.yield() 静态方法。当前线程调用此方法,使线程由running态进入runnable态,放弃cpu使用权,让cpu再次选择要执行的线程。 注:实际过程中,yield仅仅是让其它具有同等优先级的runnable线程获取执行权,但并不能保证其它具有同等优先级的线程就一定能获得cpu执行权。因为做出让步的当前线程,可能会被cpu再次选中,进入running状态。yield()不会导致阻塞。
  5. 并发编程中为什么使用while循环而不是if()来调用wait方法 当其他获取到该对象锁的线程释放锁时,上面的线程有可能被意外唤醒,但是此时上面线程是不满足条件的,导致它破坏了被锁保护的约束关系,引起意外后果。 用while()方法,就会再次判断条件是不是成立,满足执行条件了,才会继续执行;而if会直接唤醒wait()方法,继续往下执行,不管被notify或notifyAll唤醒的是不是它,而极有可能,此时并不满足if的判断条件,就是JDK文档中所谓的“虚假唤醒”。
            synchronized (Demo.class){while(!执行条件) {obj.wait();}....if(!执行条件) {obj.wait();}obj.wait();}

java 线程状态_浅析Java中的线程状态相关推荐

  1. java group类_浅析Java中线程组(ThreadGroup类)

    Java中使用ThreadGroup类来代表线程组,表示一组线程的集合,可以对一批线程和线程组进行管理.可以把线程归属到某一个线程组中,线程组中可以有线程对象,也可以有线程组,组中还可以有线程,这样的 ...

  2. java深度克隆_浅析Java中clone()方法浅克隆与深度克隆

    现在Clone已经不是一个新鲜词语了,伴随着"多莉"的产生这个词语确实很"火"过一阵子,在Java中也有这么一个概念,它可以让我们很方便的"制造&qu ...

  3. java变量同名_浅析Java中局部变量与成员变量同名解决技巧

    要想区分这哥俩,首先,我们得知道它们分别是什么.先从成员变量下刀. 成员变量 我们来研究一个事物: 属性:外在特征:例如人的身高,体重 行为:能够做什么:例如人有说话,打球等行为. 而在Java语言中 ...

  4. java怎么修改订单状态_在WooCommerce中自定义订单状态更改时发送电子邮件通知

    我在我的WooCommerce中创建了一个名为Back Order( wc-backorder )的自定义订单状态: /** * Add custom status to order list */ ...

  5. Java的反射作用_浅析Java 反射机制的用途和缺点

    反射的用途 Uses of Reflection Reflection is commonly used by programs which require the ability to examin ...

  6. java 越来越慢_浅析Java语言慢的原因

    Java在早期(比如JDK1.2以前)是很慢的,后续版本由于有许多优化手段的加入,Java正变得越来越快,所以现在也有很多关于Java和C/C++孰快孰慢的争论.我想就我自己的理解,谈一下影响Java ...

  7. java expression 用法_浅析Java 8新特性Lambda Expression

    什么是Lambda Expression 对于Lambda Expression,我的理解是,它是一个函数表达式,如下: (int x, int y) -> x - y 符号左边定义了函数的输入 ...

  8. java 多线程状态_总结Java中线程的状态及多线程的实现方式

    线程的状态线程状态图: 说明: 线程共包括以下5种状态. 1. 新建状态(New) : 线程对象被创建后,就进入了新建状态.例如,Thread thread = new Thread(). 2. 就绪 ...

  9. java 线程组作用_浅析Java中线程组(ThreadGroup类)

    一.概念 Java中使用ThreadGroup类来代表线程组,表示一组线程的集合,可以对一批线程和线程组进行管理.可以把线程归属到某一个线程组中,线程组中可以有线程对象,也可以有线程组,组中还可以有线 ...

最新文章

  1. 设计模式-职责链模式
  2. java内存区域之程序计数器
  3. Charles抓包https(测试app的双向认证)
  4. Synchronize对象锁
  5. 状态模式和策略模式的区别
  6. vs code 插件_[VSCode插件开发] 由浅入深,带你了解如何打造百万级产品
  7. 如何查看CentOS版本
  8. DataGridView插入图片
  9. 死机后硬关机造成oracle故障,电脑死机故障汇总:各种死机现象分析
  10. Jenkins执行shell命令,提示Pseudo-terminal will not be allocated because stdin is not a terminal.
  11. cacti监控H3C交换机
  12. 服务降级,限流,削峰
  13. 大学生提高计算机应用能力,大学生计算机应用能力的培养策略
  14. 紫光扫描仪ocr_清华紫光OCR下载
  15. 记一次微信分享的坑,ios和安卓分享打开的url不一样
  16. 2022 大一大二基础hive考试题
  17. MySQL 两张表关联更新(用一个表的数据更新另一个表的数据)两个表使用条件从另外一个表获取数据更新本表
  18. 计算机组装兴趣小组考核,中职计算机专业课程学生成绩考核之我见
  19. CTF---basecrack---Base编码分析工具安装详解
  20. 对“超图学习”相关优势及适用范围的学习及整理

热门文章

  1. 获取某个周在本年的开始日期和结束日期
  2. 在linux下添加路由
  3. VMware虚拟机软件
  4. linux java输出到文件,linux java输出到文件内容
  5. php分页技术的作用,分页原理技术细节剖析(php+mysql)实例
  6. tf.gfile()函数
  7. 爬虫文档学习 xpath bs4 selenium scrapy...
  8. 【每日SQL打卡】​​​​​​​​​​​​​​​DAY 8丨判断三角形【难度简单】
  9. 数据结构 - 队列(图解+源码)
  10. MySQL流浪记(一)—— 初步认识数据库的内涵