🌆 故事背景:现代城市的任务处理中心
想象一个现代化城市,有一个 "任务调度中心" 负责管理各种城市运作任务:
-
任务大厅:存放所有待处理的任务
-
工作队列:每个工作人员(线程)有自己的任务队列
-
调度室:决定哪个任务由哪个工作人员处理
-
状态监控:实时跟踪每个任务的执行状态
这个任务调度中心就是 Java 中的Thread系统,它负责创建、调度和管理线程。
🧑💼 线程的生命周期
1. 线程的五种状态
java
// Thread.State枚举
public enum State {
NEW, // 新建状态(任务刚被创建)
RUNNABLE, // 可运行状态(任务已分配给工作人员)
BLOCKED, // 阻塞状态(工作人员等待某个条件)
WAITING, // 等待状态(工作人员无限期等待)
TIMED_WAITING, // 定时等待状态(工作人员等待指定时间)
TERMINATED; // 终止状态(任务执行完毕)
}
🛠️ 线程的核心组件
1. 任务定义(Runnable 接口)
java
// 定义一个可执行的任务
class CleaningTask implements Runnable {
private final String area; // 清洁区域
public CleaningTask(String area) {
this.area = area;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() +
" 开始清洁 " + area + " 区域");
try {
Thread.sleep(2000); // 模拟清洁时间
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " 被中断");
Thread.currentThread().interrupt(); // 恢复中断状态
}
System.out.println(Thread.currentThread().getName() +
" 完成清洁 " + area + " 区域");
}
}
2. 线程创建与启动
java
public class ThreadDemo {
public static void main(String[] args) {
// 创建任务
Runnable task1 = new CleaningTask("街道");
Runnable task2 = new CleaningTask("公园");
// 创建线程(工作人员)
Thread worker1 = new Thread(task1, "清洁工1");
Thread worker2 = new Thread(task2, "清洁工2");
// 启动线程(分配任务)
System.out.println("调度中心:任务分配中...");
worker1.start(); // 启动线程,执行run()方法
worker2.start(); // 注意:不能重复调用start()
// 主线程继续执行其他任务
System.out.println("调度中心:继续处理其他事务...");
}
}
🧠 JVM 中的线程实现
1. 线程的底层实现
Java 线程在不同操作系统中的实现方式:
- Windows:每个 Java 线程映射到一个 Windows 内核线程
- Linux:使用 POSIX 线程(pthread)实现
- Solaris:支持轻量级进程(LWP)和内核线程
2. 线程的内存结构
每个线程在 JVM 中有自己的内存区域:
- 程序计数器:记录当前执行的字节码位置
- 虚拟机栈:存储局部变量、方法调用帧等
- 本地方法栈:存储本地方法调用信息
⏰ 线程调度与同步
1. 线程调度策略
java
// 设置线程优先级(1-10,默认5)
worker1.setPriority(Thread.MAX_PRIORITY); // 最高优先级10
worker2.setPriority(Thread.MIN_PRIORITY); // 最低优先级1
// 线程让步(建议调度器切换到其他线程)
Thread.yield();
// 线程加入(等待该线程执行完毕)
try {
worker1.join(); // 主线程等待worker1完成
} catch (InterruptedException e) {
e.printStackTrace();
}
2. 线程同步机制
java
// 共享资源
class SharedResource {
private int count = 0;
// 同步方法,防止多线程冲突
public synchronized void increment() {
count++; // 原子操作
System.out.println(Thread.currentThread().getName() +
" 增加计数,当前值:" + count);
}
}
// 使用同步机制的任务
class CountingTask implements Runnable {
private final SharedResource resource;
public CountingTask(SharedResource resource) {
this.resource = resource;
}
@Override
public void run() {
for (int i = 0; i < 3; i++) {
resource.increment();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
🚀 完整示例:城市任务调度系统
java
import java.util.concurrent.TimeUnit;
public class CityTaskSystem {
public static void main(String[] args) {
System.out.println("==== 城市任务调度系统启动 ====");
// 创建共享资源
SharedResource resource = new SharedResource();
// 创建并启动多个任务线程
Thread cleaner = new Thread(new CleaningTask("市中心"), "清洁工");
Thread repairman = new Thread(new RepairTask("桥梁"), "修理工");
Thread counter = new Thread(new CountingTask(resource), "计数员");
cleaner.start();
repairman.start();
counter.start();
// 主线程执行其他任务
try {
System.out.println("市长:开始视察城市...");
TimeUnit.SECONDS.sleep(3);
System.out.println("市长:视察结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
// 等待所有任务完成
try {
cleaner.join();
repairman.join();
counter.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("==== 城市任务调度系统关闭 ====");
}
}
// 清洁任务
class CleaningTask implements Runnable {
private final String area;
public CleaningTask(String area) {
this.area = area;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() +
" 收到清洁 " + area + " 的任务");
try {
for (int i = 1; i <= 3; i++) {
System.out.println(Thread.currentThread().getName() +
" 正在清洁 " + area + " 区域的 " + i + "/3");
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " 任务被中断");
}
System.out.println(Thread.currentThread().getName() +
" 完成清洁 " + area + " 区域");
}
}
// 维修任务
class RepairTask implements Runnable {
private final String facility;
public RepairTask(String facility) {
this.facility = facility;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() +
" 收到维修 " + facility + " 的任务");
try {
System.out.println(Thread.currentThread().getName() +
" 正在检查 " + facility + " 设施");
Thread.sleep(1500);
System.out.println(Thread.currentThread().getName() +
" 发现问题,开始维修");
Thread.sleep(2000);
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " 任务被中断");
}
System.out.println(Thread.currentThread().getName() +
" 完成维修 " + facility + " 设施");
}
}
// 计数任务(使用同步)
class CountingTask implements Runnable {
private final SharedResource resource;
public CountingTask(SharedResource resource) {
this.resource = resource;
}
@Override
public void run() {
for (int i = 0; i < 3; i++) {
resource.increment();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
// 共享资源类
class SharedResource {
private int count = 0;
public synchronized void increment() {
count++;
System.out.println(Thread.currentThread().getName() +
" 计数:" + count);
}
}
运行结果示例
plaintext
==== 城市任务调度系统启动 ====
市长:开始视察城市...
清洁工 收到清洁 市中心 的任务
修理工 收到维修 桥梁 的任务
计数员 计数:1
清洁工 正在清洁 市中心 区域的 1/3
修理工 正在检查 桥梁 设施
计数员 计数:2
清洁工 正在清洁 市中心 区域的 2/3
修理工 发现问题,开始维修
计数员 计数:3
清洁工 正在清洁 市中心 区域的 3/3
修理工 完成维修 桥梁 设施
市长:视察结束
清洁工 完成清洁 市中心 区域
==== 城市任务调度系统关闭 ====
🌟 Thread 核心特性总结
-
生命周期管理:
- 新建 → 可运行 → 阻塞 / 等待 → 终止
- 通过 start () 启动,run () 执行任务
-
底层实现:
- 与操作系统线程一一对应
- JVM 负责线程的创建、调度和销毁
-
线程同步:
- 使用 synchronized 关键字实现同步
- 通过 wait ()/notify () 实现线程间通信
-
线程调度:
- 优先级调度(1-10)
- 抢占式调度(由 JVM 决定执行顺序)
-
高级特性:
-
守护线程(Daemon Thread)
-
线程组(ThreadGroup)
-
线程局部变量(ThreadLocal)
-
通过这个城市任务调度系统的故事,我们理解了Thread的核心原理:它就像城市中的任务调度中心,负责创建、分配和管理各种任务。在实际开发中,Thread是实现多任务并发执行的基础,但直接使用原生 Thread 类可能会比较复杂,因此 Java 提供了更高级的线程池(ExecutorService)和并发工具类来简化开发。