jvm线程
哪吒 2023/6/15
# jvm线程
JVM线程是Java并发编程的基础,理解JVM线程的实现原理对于编写高性能、线程安全的Java应用程序至关重要。本文将深入探讨JVM线程的底层实现机制、线程模型、状态管理和调度策略。
# 1. JVM线程模型概述
# 1.1 线程的定义与重要性
在JVM中,线程是程序执行的最小单位,每个线程都有自己的程序计数器、虚拟机栈和本地方法栈,但共享堆内存和方法区。
public class ThreadBasicDemo {
public static void main(String[] args) {
// 主线程信息
Thread mainThread = Thread.currentThread();
System.out.println("主线程名称: " + mainThread.getName());
System.out.println("主线程ID: " + mainThread.getId());
System.out.println("主线程状态: " + mainThread.getState());
System.out.println("主线程优先级: " + mainThread.getPriority());
// 创建新线程
Thread workerThread = new Thread(() -> {
System.out.println("工作线程: " + Thread.currentThread().getName());
System.out.println("工作线程ID: " + Thread.currentThread().getId());
}, "WorkerThread");
workerThread.start();
try {
workerThread.join(); // 等待工作线程完成
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
# 1.2 JVM线程与操作系统线程的关系
JVM线程的实现依赖于底层操作系统的线程模型:
- 一对一模型(1:1):每个Java线程对应一个操作系统线程
- 多对一模型(N:1):多个Java线程映射到一个操作系统线程
- 多对多模型(M:N):多个Java线程映射到多个操作系统线程
现代JVM主要采用一对一模型,这样可以充分利用多核处理器的优势。
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
public class ThreadModelDemo {
public static void main(String[] args) {
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
System.out.println("当前JVM中的线程数: " + threadMXBean.getThreadCount());
System.out.println("峰值线程数: " + threadMXBean.getPeakThreadCount());
System.out.println("守护线程数: " + threadMXBean.getDaemonThreadCount());
// 获取所有线程信息
long[] threadIds = threadMXBean.getAllThreadIds();
for (long threadId : threadIds) {
System.out.println("线程ID: " + threadId + ", 线程名: " +
threadMXBean.getThreadInfo(threadId).getThreadName());
}
}
}
# 2. 线程的内存模型
# 2.1 线程私有内存区域
每个线程都有自己的私有内存区域:
public class ThreadMemoryDemo {
// 实例变量 - 存储在堆中,线程共享
private int sharedVariable = 0;
public void demonstrateThreadMemory() {
// 局部变量 - 存储在线程私有的虚拟机栈中
int localVariable = 100;
Thread thread1 = new Thread(() -> {
// 每个线程都有自己的局部变量副本
int threadLocal = localVariable + 1;
System.out.println("Thread1 - threadLocal: " + threadLocal);
// 但共享实例变量
synchronized (this) {
sharedVariable++;
System.out.println("Thread1 - sharedVariable: " + sharedVariable);
}
});
Thread thread2 = new Thread(() -> {
int threadLocal = localVariable + 2;
System.out.println("Thread2 - threadLocal: " + threadLocal);
synchronized (this) {
sharedVariable++;
System.out.println("Thread2 - sharedVariable: " + sharedVariable);
}
});
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
public static void main(String[] args) {
new ThreadMemoryDemo().demonstrateThreadMemory();
}
}
# 2.2 程序计数器(PC Register)
程序计数器是线程私有的内存区域,用于存储当前线程正在执行的字节码指令的地址。
public class PCRegisterDemo {
public static void main(String[] args) {
Runnable task = () -> {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() +
" - 执行第 " + i + " 次循环");
// 每个线程都有自己的程序计数器
// 记录当前执行到哪一条字节码指令
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
};
Thread thread1 = new Thread(task, "Thread-1");
Thread thread2 = new Thread(task, "Thread-2");
thread1.start();
thread2.start();
}
}
# 2.3 虚拟机栈(JVM Stack)
虚拟机栈是线程私有的,用于存储局部变量、操作数栈、动态链接和方法返回地址。
public class JVMStackDemo {
public static void main(String[] args) {
new JVMStackDemo().demonstrateStack();
}
public void demonstrateStack() {
// 每个方法调用都会在虚拟机栈中创建一个栈帧
int localVar = 10; // 局部变量存储在栈帧中
System.out.println("方法开始执行,局部变量: " + localVar);
// 递归调用会在栈中创建多个栈帧
recursiveMethod(5);
System.out.println("方法执行结束");
}
private void recursiveMethod(int depth) {
if (depth <= 0) {
return;
}
// 每次递归调用都会创建新的栈帧
int currentDepth = depth;
System.out.println("递归深度: " + currentDepth +
", 线程: " + Thread.currentThread().getName());
recursiveMethod(depth - 1);
}
}
# 3. 线程状态与生命周期
# 3.1 Java线程状态
Java线程有六种状态,定义在Thread.State枚举中:
import java.util.concurrent.TimeUnit;
public class ThreadStateDemo {
public static void main(String[] args) throws InterruptedException {
// 1. NEW状态 - 线程创建但未启动
Thread newThread = new Thread(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}, "NewThread");
System.out.println("创建后的状态: " + newThread.getState()); // NEW
// 2. RUNNABLE状态 - 线程正在运行或准备运行
newThread.start();
System.out.println("启动后的状态: " + newThread.getState()); // RUNNABLE
// 3. TIMED_WAITING状态 - 线程等待指定时间
Thread.sleep(100);
System.out.println("睡眠中的状态: " + newThread.getState()); // TIMED_WAITING
// 4. WAITING状态演示
Object lock = new Object();
Thread waitingThread = new Thread(() -> {
synchronized (lock) {
try {
lock.wait(); // 进入WAITING状态
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}, "WaitingThread");
waitingThread.start();
Thread.sleep(100);
System.out.println("等待中的状态: " + waitingThread.getState()); // WAITING
// 5. BLOCKED状态演示
Object blockLock = new Object();
Thread blockingThread = new Thread(() -> {
synchronized (blockLock) {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}, "BlockingThread");
Thread blockedThread = new Thread(() -> {
synchronized (blockLock) { // 尝试获取已被占用的锁
System.out.println("获得锁");
}
}, "BlockedThread");
blockingThread.start();
Thread.sleep(100);
blockedThread.start();
Thread.sleep(100);
System.out.println("阻塞中的状态: " + blockedThread.getState()); // BLOCKED
// 唤醒等待线程
synchronized (lock) {
lock.notify();
}
// 等待所有线程结束
newThread.join();
waitingThread.join();
blockingThread.join();
blockedThread.join();
// 6. TERMINATED状态 - 线程执行完毕
System.out.println("结束后的状态: " + newThread.getState()); // TERMINATED
}
}
# 3.2 线程状态转换图
public class ThreadStateTransitionDemo {
public static void main(String[] args) {
System.out.println("=== 线程状态转换演示 ===");
// 创建状态监控线程
Thread monitorThread = new Thread(() -> {
Thread targetThread = Thread.currentThread();
while (!Thread.currentThread().isInterrupted()) {
try {
Thread.sleep(500);
System.out.println("当前状态: " + targetThread.getState());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
});
// 创建被监控的线程
Thread targetThread = new Thread(() -> {
try {
System.out.println("线程开始执行");
// RUNNABLE -> TIMED_WAITING
Thread.sleep(1000);
// TIMED_WAITING -> RUNNABLE
System.out.println("睡眠结束,继续执行");
// 同步块演示
synchronized (ThreadStateTransitionDemo.class) {
Thread.sleep(1000);
}
System.out.println("线程执行完毕");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("线程被中断");
}
}, "TargetThread");
// 启动监控
monitorThread.start();
try {
Thread.sleep(100);
System.out.println("目标线程创建后状态: " + targetThread.getState());
targetThread.start();
targetThread.join();
System.out.println("目标线程结束后状态: " + targetThread.getState());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
monitorThread.interrupt();
}
}
}
# 4. 线程调度机制
# 4.1 线程优先级
JVM使用线程优先级来影响线程调度,但具体的调度策略依赖于操作系统。
public class ThreadPriorityDemo {
public static void main(String[] args) {
System.out.println("=== 线程优先级演示 ===");
// 创建不同优先级的线程
Thread lowPriorityThread = new Thread(() -> {
for (int i = 0; i < 10; i++) {
System.out.println("低优先级线程: " + i);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}, "LowPriorityThread");
Thread normalPriorityThread = new Thread(() -> {
for (int i = 0; i < 10; i++) {
System.out.println("普通优先级线程: " + i);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}, "NormalPriorityThread");
Thread highPriorityThread = new Thread(() -> {
for (int i = 0; i < 10; i++) {
System.out.println("高优先级线程: " + i);
try {
Thread.sleep(10);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}, "HighPriorityThread");
// 设置优先级
lowPriorityThread.setPriority(Thread.MIN_PRIORITY); // 1
normalPriorityThread.setPriority(Thread.NORM_PRIORITY); // 5
highPriorityThread.setPriority(Thread.MAX_PRIORITY); // 10
System.out.println("低优先级: " + lowPriorityThread.getPriority());
System.out.println("普通优先级: " + normalPriorityThread.getPriority());
System.out.println("高优先级: " + highPriorityThread.getPriority());
// 启动线程
lowPriorityThread.start();
normalPriorityThread.start();
highPriorityThread.start();
try {
lowPriorityThread.join();
normalPriorityThread.join();
highPriorityThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
# 4.2 线程调度策略
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ThreadSchedulingDemo {
public static void main(String[] args) {
System.out.println("=== 线程调度策略演示 ===");
// 1. 抢占式调度演示
demonstratePreemptiveScheduling();
// 2. 时间片轮转演示
demonstrateTimeSlicing();
// 3. 协作式调度演示
demonstrateCooperativeScheduling();
}
// 抢占式调度
private static void demonstratePreemptiveScheduling() {
System.out.println("\n--- 抢占式调度 ---");
Thread cpuIntensiveThread = new Thread(() -> {
long startTime = System.currentTimeMillis();
while (System.currentTimeMillis() - startTime < 2000) {
// CPU密集型任务
Math.sqrt(Math.random());
}
System.out.println("CPU密集型线程完成");
}, "CPUIntensiveThread");
Thread ioThread = new Thread(() -> {
try {
for (int i = 0; i < 5; i++) {
System.out.println("IO线程执行: " + i);
Thread.sleep(200); // 模拟IO操作
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}, "IOThread");
cpuIntensiveThread.start();
ioThread.start();
try {
cpuIntensiveThread.join();
ioThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
// 时间片轮转
private static void demonstrateTimeSlicing() {
System.out.println("\n--- 时间片轮转 ---");
for (int i = 0; i < 3; i++) {
final int threadId = i;
Thread thread = new Thread(() -> {
for (int j = 0; j < 10; j++) {
System.out.println("线程" + threadId + " - 执行" + j);
// 主动让出CPU,模拟时间片结束
Thread.yield();
}
}, "Thread-" + i);
thread.start();
}
}
// 协作式调度
private static void demonstrateCooperativeScheduling() {
System.out.println("\n--- 协作式调度 ---");
Object lock = new Object();
Thread producer = new Thread(() -> {
synchronized (lock) {
for (int i = 0; i < 5; i++) {
System.out.println("生产者生产: " + i);
lock.notify(); // 通知消费者
try {
if (i < 4) lock.wait(); // 等待消费者
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
}
}, "Producer");
Thread consumer = new Thread(() -> {
synchronized (lock) {
for (int i = 0; i < 5; i++) {
try {
lock.wait(); // 等待生产者
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
System.out.println("消费者消费: " + i);
lock.notify(); // 通知生产者
}
}
}, "Consumer");
producer.start();
consumer.start();
try {
producer.join();
consumer.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}