当前位置: 首页 > news >正文

Java多线程(3)

Java多线程(3)

深入剖析Java线程的生命周期,探秘JVM的线程状态!

img

线程的生命周期

Java 线程的生命周期主要包括五个阶段:新建、就绪、运行、阻塞和销毁。

img

  • **新建(New):**线程对象通过 new 关键字创建,但还未调用 start() 方法时,线程处于新建状态。此时,线程对象已经分配了内存空间,但尚未启动执行。
  • **就绪(Runnable):**线程对象调用 start() 方法后,线程处于就绪状态。此时,线程已经准备好执行,但还没有获得 CPU 时间片。多个线程处于就绪状态时,由 Java 虚拟机的线程调度器来决定哪个线程获得 CPU 时间片开始执行。
  • **运行(Running):**当线程获得 CPU 时间片开始执行时,线程处于运行状态。此时,线程的 run() 方法正在被执行。
  • **阻塞(Blocked):**在特定情况下,线程可能会被暂时挂起,进入阻塞状态。例如,线程调用了 sleep() 方法、等待 I/O 操作、获得了某个对象的锁但没有获取到锁等。当阻塞状态的条件解除时,线程会重新进入就绪状态,等待获取 CPU 时间片继续执行。
  • **销毁(Terminated):**线程执行完 run() 方法后,或者调用了 stop() 方法,线程将进入销毁状态。一旦线程进入了销毁状态,就无法再恢复到其他状态。

Java 线程状态的分析

**在 Java 虚拟机(JVM)中,线程的状态主要分为 new、runnable、blocked、waiting、timed_waiting和terminated 六种状态,**让我们一一来了解:

img

  • **new:**当我们创建一个线程对象时,线程就处于 new状态。此时,线程对象已经被创建,但还没有开始执行。
  • **runnable:**当线程调用 start() 方法后,线程就进入了runnable状态。此时,线程已经准备好执行,但还没有获得 CPU 的执行时间片,处于等待 CPU 调度的状态。
  • **blocked:**在线程执行过程中,可能会因为等待锁资源而暂时无法继续执行,此时线程就进入了 blocked状态。例如,在多线程并发访问共享资源时,如果一个线程已经持有了某个对象的锁,其他线程就无法获取该锁,进而被阻塞。
  • **waiting:**在某些情况下,线程可能会主动调用 wait()方法,进入 waiting 状态。例如,线程等待某个条件的满足,或者等待其他线程的通知。在 waiting 状态下,线程会被挂起,直到被其他线程唤醒。
  • **timed_waiting:**类似于waiting状态,但是在timed_waiting 状态下,线程会在一定的时间内等待。例如,线程调用了 sleep() 方法、join() 方法或者等待某个锁的过程中,会进入 timed_waiting 状态。一旦等待时间到达或者锁被释放,线程会重新进入runnable 状态。
  • **terminated:**线程的任务执行完毕,或者出现异常导致线程终止,线程就进入了 terminated 状态。一旦线程进入 terminated 状态,就无法再被启动和执行。

实际案例演示

为了更好地理解 Java 线程的生命周期,让我们来看一个实际的电商项目案例,通过简单的 Java 代码演示不同线程状态的变化。

假设我们有一个电商项目,其中包含了商品库存管理和订单处理两个模块。商品库存管理模块负责更新商品库存数量,而订单处理模块负责处理用户提交的订单。

在这个案例中,我们可以创建两个线程,分别模拟商品库存管理和订单处理两个模块的并发执行。

首先,我们创建一个商品库存管理线程,使用 synchronized关键字保证在修改库存数量时的线程安全性。

img

然后,我们创建一个订单处理线程,使用 Lock 和 Condition 来控制线程的阻塞和唤醒。

img

在主线程中,我们创建并启动这两个线程,并演示线程状态的变化。

img

在运行这段代码时,我们可以观察到以下线程状态的变化:

商品库存管理线程(InventoryManagementThread)的线程状态:

  • **new:**在调用 start() 方法创建线程对象后,线程进入new状态,表示线程对象已经被创建但尚未启动。
  • **runnable:**在调用 start() 方法后,线程开始运行并进入 runnable 状态,表示线程处于可运行状态,但不一定正在执行。在这个案例中,我们可以看到线程在运行时通过输出语句显示了商品库存数量的变化,处于 runnable 状态。
  • **terminated:**当线程执行完 run() 方法中的代码或者调用了 stop() 方法后,线程进入 terminated 状态,表示线程执行完毕并终止。

订单处理线程(OrderProcessingThread)的线程状态:

  • **new:**在调用 start() 方法创建线程对象后,线程进入new 状态,表示线程对象已经被创建但尚未启动。
  • **runnable:**在调用 start() 方法后,线程开始运行并进入 runnable 状态,表示线程处于可运行状态,但不一定正在执行。在这个案例中,订单处理线程在订单未提交时通过调用 condition.await() 方法进入了阻塞状态,处于 runnable 状态。
  • **blocked:**在订单未提交时,订单处理线程通过调用condition.await() 方法进入了阻塞状态,表示线程因为等待某个条件而被阻塞,处于 blocked 状态。
  • **runnable:**当订单提交后,订单处理线程通过调用condition.signal() 方法被唤醒并继续执行,进入runnable 状态。
  • **terminated:**当线程执行完 run() 方法中的代码或者调用了 stop() 方法后,线程进入 terminated 状态,表示线程执行完毕并终止。

通过以上案例,我们可以清楚地看到不同线程状态的转换,包括 new、runnable、blocked、terminated 等状态。

总结

ated 状态,表示线程执行完毕并终止。

通过以上案例,我们可以清楚地看到不同线程状态的转换,包括 new、runnable、blocked、terminated 等状态。

总结

**Java线程的生命周期包括新建、就绪、运行、阻塞和销毁五个阶段。根据JVM的源码分析,线程的状态可以分为new、runnable、blocked、waiting、timed_waiting和terminated六种状态。**在实际项目中,了解线程的生命周期和状态对于编写高效的多线程程序非常重要。合理地管理和控制线程的状态转换,可以提高程序的并发性能和稳定性。

http://www.lryc.cn/news/235811.html

相关文章:

  • Java线程周期
  • map与set的封装
  • mac无法向移动硬盘拷贝文件怎么解决?不能读取移动硬盘文件怎么解决
  • 基于Netty实现的简单聊天服务组件
  • 视频封面:从视频中提取封面,轻松制作吸引人的视频
  • CICD 持续集成与持续交付——gitlab
  • Linux - 驱动开发 - RNG框架
  • qsort使用举例和qsort函数的模拟实现
  • AttributeError: module ‘gradio‘ has no attribute ‘ClearButton‘解决方案
  • Kafka 集群如何实现数据同步?
  • 一本了解生成式人工智能
  • git 相关指令总结(持续更新中......)
  • windows 安装 Oracle Database 19c
  • 【数据结构】图的存储结构(邻接矩阵)
  • kubernetes--Pod控制器详解
  • 九、Linux用户管理
  • springboot项目中没有识别到yml文件解决办法
  • [管理与领导-125]:一个IT人的思考:职场中、人际交往中,不要为他人的不良行为和言语买单,不要让自己的情绪被外界影响或掌控。
  • 【FPGA】IP核
  • 吾爱破解置顶的“太极”,太好用了吧!
  • Postman接收列表、数组参数@RequestParam List<String> ids
  • qemu + busybox + 内核实验环境搭建(2023-11)
  • JavaScript管理HTMLDOM元素(增删改查)
  • RE2文本匹配实战
  • 实在智能携手中国电信翼支付,全球首款Agent智能体亮相2023数字科技生态大会
  • 安全框架springSecurity+Jwt+Vue-1(vue环境搭建、动态路由、动态标签页)
  • React整理总结(三)
  • 天气这么好,都外出了。顺便了解一下漏桶算法
  • 【FPGA】Verilog:实现 RS 触发器 | Flip-Flop | 使用 NOR 的 RS 触发器 | 使用 NAND 的 RS 触发器
  • 【技术追踪】SAM(Segment Anything Model)代码解析与结构绘制之Mask Decoder