网站首页 > java教程 正文
最近在悟空问答上面经常见到有人咨询关于Java并发编程的问题,因此准备写一些文章进行这方面的介绍,以帮助有疑惑的人,或者是即使没有疑惑但确实是没有时间整理的人。本文是第一部分,主要介绍Java线程六种状态及其转换,并附加编码实例。好多文章介绍Java线程是5种状态,分别为为初始状态(new),就绪状态(Runnable),运行状态(Running)、阻塞状态(Blocked),终止状态(Dead)。
实际上本人更倾向于六种状态,理由主要是基于Thread的源码并通过编程进行了验证。在Thread源码的状态枚举类型中,实际上定义了六种状态,分别是初始状态(NEW)、运行状态(RUNNABLE)、阻塞状态(BLOCKED)、等待(WAITING)、超时等待(TIMED_WAITING)、终止(TERMINATED)六种状态。下面分别将分别介绍这六种状态:
- 初始状态(NEW):实例化线程对象未调用start方法之前,线程处于初始状态。
- 运行状态(RUNNABLE):实际运行状态包括就绪(ready,即被主线程或其他线程调用start方法启动)和运行中(running,获取CPU执行时间,线程得以执行)两种状态。
- 阻塞(BLOCKED):获取锁或其他资源之前线程被阻塞,处于阻塞状态。
- 等待(WAITING):进入该状态的线程需要等待其他线程通知或被中断。
- 超时等待(TIMED_WAITING):该状态与WAITING状态不同的是,它可以在指定的时间后自行返回。
- 终止(TERMINATED):表示该线程执行结束。
如果想查看线程状态源码,可参见Thread类:
下面看一下这六种状态是如何转换的:
我们知道Java线程主要通过两种方式来实现,一种是实现Runnable接口,一种是继承Thread类。线程被创建并被启动后,就开始了它的生命周期。Java线程的生命周期有长又有短,并且在其生命周期内进行各种状态的转化。线程在被实例化时进入NEW状态,调用start方法后会进入Runnable状态。Runnable可以说一种核心状态,Runnable与Waiting、Timed_Waiting、Blocked等状态进行转化,直至执行完成进入TERMINATED状态。
Runnable和Waiting状态之间的转化,主要在线程内调用Object.wait()、Thread.join()、LockSupport.park()方法时进入Waiting状态。当其他线程调用Object.notify()随机通知单线程,Objec.notifyAll()通知所有线程,LockSupport.unpark(Thread)方法时被唤醒,若其他线程不释放资源,线程将一直处于Waiting状态。
Runnable和Timed_Waiting状态之间的转化,主要是线程内调用Thread.sleep(long)、Objec.wait(long)等方法时进入Timed_Waiting状态。当其他与其竞争资源的线程调用Object.notify()、Objec.notifyAll()等方法时线程会被唤醒。当超过超时时间时线程也会自动唤醒,这也是Timed_Waiting状态与Waiting状态的最大区别。
当线程尝试获取锁而未获取到时,线程从Runnable状态进入Blocked状态。而当线程获取到锁后从Blocked状态进入Runnable状态。
下面将结合代码示例和jconsole来查看进程的不同状态。本文主要是通过生产者和消费者示例程序来验证Java 线程的各种状态。在示例中启动了一个消费者和两个生产者,先启动消费者后等待,再启动生产者休眠一段时间后,开始进行生产。当生产到一定数量后,通知消费者开始消费,最后一边生产一边消费。
主程序:
生产者run方法:
消费者run方法:
执行主程序,查看程序的状态。
初始启动后,各程序处于NEW状态:
查看consumer状态,因为程序执行了object.wait(),程序处于WAITING状态:
consumer消费一个产品后,会调用Thread.sleep()类,程序就进入TIMED_WAITING状态:
生产者和消费者在生产或消费时都会操作list,竞争锁synchronized(list),此时会进入BLOCKED状态:
程序在执行过程中处于RUNNABLE状态:
当然还有一种状态是TERMINATED,这个比较好理解,程序执行完成处于终止状态,不再详细描述。
附录:
主要是讲述一下如何进入console查看线程状态。
配置好Java环境变量后,执行jconsole命令:
进入jconsole界面,选择你执行的程序:
点击进入,查看你的线程:
喜欢动手的阅读者,可能会发现一个bug,不知道你发现了没有?
本人具有多年的java开发经验,熟悉多种框架,熟悉网络编程,熟悉java安全编程,熟悉大数据,熟悉多种安全协议,熟悉并发编程,有兴趣的同学可以互相关注,互相学习!!!
猜你喜欢
- 2024-10-25 java 并发编程实战(第二章)(java并发编程深度解析)
- 2024-10-25 Java 多线程并发编程面试笔录一览
- 2024-10-25 我和面试官的博弈:Java 并发编程篇
- 2024-10-25 清华大牛出版的java并发编程从入门到精通,不要让它继续蒙灰了
- 2024-10-25 JAVA多线程并发编程-避坑指南(java多线程并发调用接口)
- 2024-10-25 阿里大神再秀神作!凭借“347页核心笔记”带你玩转并发编程
- 2024-10-25 Java并发编程实战:深入理解线程池
- 2024-10-25 Java并发编程实践简单案例-顾客排队
- 2024-10-25 2020程序员都在看的PDF:《Java 多线程编程实战指南(核心篇)》
- 2024-10-25 12W字!阿里P8架构师手写“Java并发手册”带你横扫全网
你 发表评论:
欢迎- 最近发表
-
- Java内存溢出紧急处理:10个必知的Linux命令快速定位OOM
- 面试常问的 25+ 个 Linux 命令(linux面试命令大全)
- Java堆外内存溢出紧急处理实战:Linux命令定位与Spring Boot解决
- java开发常用的Linux命令,高频的没你想象的多
- Java 应用 CPU 飙升?8 个 Linux 命令组合拳快速锁定异常线程
- Java 开发者线上问题排查常用的 15 个 Linux 命令
- Java程序员必备的Linux命令:让你的工作效率翻倍
- Java程序员必备的Linux命令全解析
- [超全整理] Java 程序员必备的 100 条 Linux 命令大全
- SAP ABAP资源导航(sap aatp)
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)