这篇说说如何从JVM的角度来理解线程,可以对Java的线程模型有一个更加深入的理解,对GC的一些细节也会理解地更加深刻。本文基于HotSpot的OpenJDK7实现。
我们知道JVM主要是用C++实现的,JVM定义的Thread的类继承结构如下:
Class hierarchy
- Thread
- NamedThread
- VMThread
- ConcurrentGCThread
- WorkerThread
- GangWorker
- GCTaskThread
- JavaThread
- WatcherThread
另外还有一个重要的类OSThread不在这个继承关系里,它以组合的方式被Thread类所使用
这些类构成了JVM的线程模型,其中最主要的是下面几个类:
java.lang.Thread: 这个是Java语言里的线程类,由这个Java类创建的instance都会 1:1 映射到一个操作系统的osthread
JavaThread: JVM中C++定义的类,一个JavaThread的instance代表了在JVM中的java.lang.Thread的instance, 它维护了线程的状态,并且维护一个指针指向java.lang.Thread创建的对象(oop)。它同时还维护了一个指针指向对应的OSThread,来获取底层操作系统创建的osthread的状态
OSThread: JVM中C++定义的类,代表了JVM中对底层操作系统的osthread的抽象,它维护着实际操作系统创建的线程句柄handle,可以获取底层osthread的状态
VMThread: JVM中C++定义的类,这个类和用户创建的线程无关,是JVM本身用来进行虚拟机操作的线程,比如GC。
有两种方式可以让用户在JVM中创建线程
1. new java.lang.Thread().start()
2. 使用JNI将一个native thread attach到JVM中
针对 new java.lang.Thread().start()这种方式,只有调用start()方法的时候,才会真正的在JVM中去创建线程,主要的生命周期步骤有:
1. 创建对应的JavaThread的instance
2. 创建对应的OSThread的instance
3. 创建实际的底层操作系统的native thread
4. 准备相应的JVM状态,比如ThreadLocal存储空间分配等
5. 底层的native thread开始运行,调用java.lang.Thread生成的Object的run()方法
6. 当java.lang.Thread生成的Object的run()方法执行完毕返回后,或者抛出异常终止后,终止native thread
7. 释放JVM相关的thread的资源,清除对应的JavaThread和OSThread
针对JNI将一个native thread attach到JVM中,主要的步骤有:
1. 通过JNI call AttachCurrentThread申请连接到执行的JVM实例
2. JVM创建相应的JavaThread和OSThread对象
3. 创建相应的java.lang.Thread的对象
4. 一旦java.lang.Thread的Object创建之后,JNI就可以调用Java代码了
5. 当通过JNI call DetachCurrentThread之后,JNI就从JVM实例中断开连接
6. JVM清除相应的JavaThread, OSThread, java.lang.Thread对象
从JVM的角度来看待线程状态的状态有以下几种:
其中主要的状态是这5种:
_thread_new: 新创建的线程
_thread_in_Java: 在运行Java代码
_thread_in_vm: 在运行JVM本身的代码
_thread_in_native: 在运行native代码
_thread_blocked: 线程被阻塞了,包括等待一个锁,等待一个条件,sleep,执行一个阻塞的IO等
从OSThread的角度,JVM还定义了一些线程状态给外部使用,比如用jstack输出的线程堆栈信息中线程的状态:
比较常见有:
Runnable: 可以运行或者正在运行的
MONITOR_WAIT: 等待锁
OBJECT_WAIT: 执行了Object.wait()之后在条件队列中等待的
SLEEPING: 执行了Thread.sleep()的
从JavaThread的角度,JVM定义了一些针对Java Thread对象的状态,基本类似,多了一个TIMED_WAITING的状态,用来表示定时阻塞的状态
最后来看一下JVM内部的VM Threads,主要由几类:
VMThread: 执行JVM本身的操作
Periodic task thread: JVM内部执行定时任务的线程
GC threads: GC相关的线程,比如单线程/多线程的GC收集器使用的线程
Compiler threads: JIT用来动态编译的线程
Signal dispatcher thread: Java解释器Interceptor用来辅助safepoint操作的线程
具体的VMThread的作用,会在讲safepoint的时候细说,就写到这里吧
相关推荐
* 最后的加餐环节是带着你理解 Java 内存模型:见识多线程读写共享数据的原子性、可见性、有序性,以及很多人解释不清楚的 happens-before 规则。当然还不能少了 CAS 和 synchronized 优化。 主讲内容 第一章:...
十一、聊聊 Java 的 GC 机制 Java 的 GC 机制是 Java 的垃圾回收机制,GC 机制的目的是释放垃圾对象的内存。GC 机制包括垃圾回收器、垃圾回收算法和垃圾回收的频率等。 十二、CMS 和 G1 的区别 CMS 和 G1 是 Java...
### 聊一聊JVM中的垃圾回收算法? JVM中的垃圾回收算法主要包括: 1. **标记-清除算法**:分为“标记”和“清除”两个阶段。标记阶段标记出所有需要回收的对象,清除阶段则回收被标记的对象占用的空间。这种算法的...
在深入理解JVM内存管理和垃圾收集器之前,我们需要先了解JVM内存模型的基本结构。 内存模型主要包括以下几个部分: 1. **Java堆**:这是JVM管理的最大的内存区域,所有线程共享,主要用于存储类实例和数组。堆内存...
volatile 可以确保共享变量在多线程环境下的可见性,它通过CPU的Lock指令实现,使得每次读取数据时都会从主内存中获取最新值,而不是使用CPU缓存。然而,volatile 无法保证原子性,例如对于`i++`这样的操作,需要...
在32位JVM中,它包含对象的HashCode、锁标志位和分代年龄等,而在64位JVM中,信息更丰富,如偏向锁的ThreadID、Epoch等。锁状态会随着锁的升级而变化,从无锁到偏向锁,再到轻量级锁和重量级锁。 5. 锁升级过程:锁...
- 掌握JVM参数设置,理解JVM内存模型和垃圾回收机制。 - **知识点10:SpringBoot类加载** - SpringBoot启动过程中的类加载顺序和机制。 - 理解SpringBoot启动时如何初始化组件和服务。 - **知识点11:MySQL查询...
Java 基础、容器、多线程、反射、对象拷贝、Java Web 模块、异常、网络、设计模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate、Mybatis、RabbitMQ、Kafka、Zookeeper、MySql、Redis、JVM 。...
“JAVA面试题解惑系列(八)——聊聊基本类型(内置类型)”涵盖了Java的原始数据类型,包括int、char、boolean等,它们与引用类型的不同之处以及它们的默认值和范围。 “JAVA面试题解惑系列(九)——继承、多态、...
这个项目旨在实现一个基础的交互式聊天功能,允许用户通过私聊或公聊进行实时沟通。以下是对该聊天室系统的核心知识点的详细说明: 1. **Java基础知识**:项目基于Java SE(Java Standard Edition),它是Java平台...
Java是一种面向对象的编程语言,具有平台独立性、多线程支持、网络编程支持等特点。Java语言的设计目标是“一次编写,到处运行”,因此Java语言可以在不同的操作系统上运行。 1. 面向对象和面向过程的区别 面向...
它以其“一次编写,到处运行”的特性而闻名,因为Java应用程序可以在任何安装了Java虚拟机(JVM)的平台上运行。Java的核心设计理念是“简单、面向对象、健壮、安全”,这使得它成为开发各种类型应用程序的理想选择...
从压缩包文件名称列表来看,有五个版本的MyQQ(0.1到0.5),这暗示了软件的开发是一个迭代过程。每个版本可能包含不同的功能改进、bug修复或性能优化。通常,开发者会按照一定的版本控制策略,如Git,来管理代码的...
6. **私聊与群聊**:在聊天室中实现私聊和群聊功能,需要设计合理的数据结构来存储用户和会话信息。可能用到ArrayList、LinkedList等集合类,以及可能的HashMap来快速查找和匹配用户。 7. **截图功能**:`GuiCamera...
面试题包含了不同技术层面的面试问题,同时也能对一些没有面试开发经验的小白给予不可估量的包装, 让你的薪水绝对翻倍, 本人亲试有效.Java面试题84集、java面试专属及面试必问课程...└─面试必问-聊聊哈希算法与HashMap
下面将详细讨论C++与Java之间的异同以及如何从C/C++过渡到Java编程。 首先,C++是C语言的一个扩展,增加了面向对象编程(OOP)的概念,如类、对象、继承、多态等,同时保留了C语言的底层控制能力。C++适合开发系统...
【Java面试核心知识点详解】 1. **面向对象的特点**:面向对象编程的三大特性是封装、继承和多态。封装是将数据和操作数据的方法捆绑在一起,形成一...理解并掌握这些知识点,将有助于在面试中展现出扎实的Java技能。
它以其“一次编写,到处运行”的理念而闻名,因为Java代码可以被编译成字节码,然后在任何支持Java虚拟机(JVM)的平台上运行。Java具有丰富的类库,支持各种应用领域,包括网络、数据库交互、图形用户界面(GUI)...
综上所述,超级课程表的技术选型涵盖了多个层面,从全文搜索、缓存/存储策略到分布式爬虫、即时通讯系统,再到内核优化与JVM调优,每个阶段的选择都是为了更好地应对业务增长带来的挑战。这些技术实践不仅有助于提升...
8. **Java虚拟机(JVM)**:了解JVM的工作原理,如内存模型(堆、栈、方法区等),垃圾回收机制,以及如何通过JVM参数调优,对于优化Java程序性能和解决内存问题非常有帮助。 9. **Java开发工具**:Eclipse、...