线程基础详解
一、知识概述
线程是Java并发编程的基础单元。理解线程的生命周期、创建方式、调度机制和基本操作,是掌握Java并发编程的第一步。本文将深入讲解线程的核心概念和实践技巧。
线程概览
┌─────────────────────────────────────────────────────────────────────┐
│ Java线程体系 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Thread 类层次 │ │
│ ├─────────────────────────────────────────────────────────────┤ │
│ │ │ │
│ │ java.lang.Thread │ │
│ │ ├── 继承Thread创建线程 │ │
│ │ └── 实现Runnable接口创建线程 │ │
│ │ │ │
│ │ java.util.concurrent │ │
│ │ ├── ExecutorService (线程池) │ │
│ │ ├── Future<T> (异步结果) │ │
│ │ ├── Callable<V> (可返回任务) │ │
│ │ └── CompletableFuture (异步编排) │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ 线程状态转换: │
│ ┌──────┐ start() ┌─────────┐ │
│ │ NEW │───────────►│ RUNNABLE │◄────────┐ │
│ └──────┘ └────┬────┘ │ │
│ │ │ │
│ ┌──────────────┼──────────────┤ │
│ ▼ ▼ ▼ │
│ ┌─────────┐ ┌─────────┐ ┌──────────────┐ │
│ │ BLOCKED │ │ WAITING │ │TIMED_WAITING │ │
│ └────┬────┘ └────┬────┘ └──────┬───────┘ │
│ │ │ │ │
│ └──────────────┴──────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────┐ │
│ │TERMINATED │ │
│ └───────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
进程与线程
| 特性 | 进程 | 线程 |
|---|
| 定义 | 资源分配的基本单位 | CPU调度的基本单位 |
| 内存 | 独立地址空间 | 共享进程内存 |
| 通信 | IPC(管道、消息队列等) | 直接读写共享变量 |
| 开销 | 创建/切换开销大 | 创建/切换开销小 |
| 稳定性 | 进程间相互隔离 | 一个线程崩溃可能影响整个进程 |
二、知识点详细讲解
2.1 线程的创建
2.1.1 三种创建方式
public class ThreadCreationDemo {
public static void main(String[] args) {
System.out.println("=== 线程创建方式 ===\n");
class MyThread extends Thread {
@Override
public void run() {
System.out.println("方式1: 继承Thread类 - " + Thread.currentThread().getName());
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("方式2: 实现Runnable接口 - " + Thread.currentThread().getName());
}
}
class MyCallable implements java.util.concurrent.Callable<String> {
@Override
public String call() throws Exception {
Thread.sleep(100);
return "方式3: 实现Callable接口 - " + Thread.currentThread().getName();
}
}
Thread thread1 = new MyThread();
thread1.start();
Thread thread2 = new Thread(new MyRunnable());
thread2.start();
Thread thread2Lambda = new Thread(() -> {
System.out.println("方式2(Lambda): " + Thread.currentThread().getName());
});
thread2Lambda.start();
java.util.concurrent.ExecutorService executor =
java.util.concurrent.Executors.newSingleThreadExecutor();
java.util.concurrent.Future<String> future = executor.submit(new MyCallable());
try {
System.out.println(future.get());
} catch (Exception e) {
e.printStackTrace();
}
executor.shutdown();
compareCreationMethods();
}
private static void compareCreationMethods() {
System.out.println("\n【三种创建方式对比】\n");
System.out.println("┌─────────────────┬─────────────────┬─────────────────┐");
System.out.println("│ 方式 │ 优点 │ 缺点 │");
System.out.println("├─────────────────┼─────────────────┼─────────────────┤");
System.out.println("│ 继承Thread │ 简单直接 │ 不支持多继承 │");
System.out.println("├─────────────────┼─────────────────┼─────────────────┤");
System.out.println("│ 实现Runnable │ 支持多继承 │ 无返回值 │");
System.out.println("│ │ 资源共享 │ │");
System.out.println("├─────────────────┼─────────────────┼─────────────────┤");
System.out.println("│ 实现Callable │ 有返回值 │ 使用稍复杂 │");
System.out.println("│ │ 可抛异常 │ │");
System.out.println("└─────────────────┴─────────────────┴─────────────────┘");
System.out.println();
System.out.println("推荐使用:");
System.out.println(" 1. 优先使用实现Runnable/Callable接口");
System.out.println(" 2. 配合线程池使用");
System.out.println(" 3. 避免直接继承Thread类");
System.out.println();
}
}
2.1.2 Thread类构造方法
public class ThreadConstructorDemo {
public static void main(String[] args) {
System.out.println("=== Thread构造方法 ===\n");
System.out.println("常用构造方法:");
System.out.println();
Thread t1 = new Thread();
System.out.println("无参构造: " + t1.getName());
Thread t2 = new Thread(() -> System.out.println("执行任务"));
System.out.println("指定任务: " + t2.getName());
Thread t3 = new Thread("my-thread");
System.out.println("指定名字: " + t3.getName());
Thread t4 = new Thread(() -> {}, "worker-thread");
System.out.println("任务+名字: " + t4.getName());
ThreadGroup group = new ThreadGroup("my-group");
Thread t5 = new Thread(group, () -> {}, "group-thread");
System.out.println("线程组: " + t5.getThreadGroup().getName());
Thread t6 = new Thread(null, () -> {}, "big-stack-thread", 1024 * 1024);
System.out.println("指定栈大小: " + t6.getName());
System.out.println();
System.out.println("命名规范:");
System.out.println(" - 使用有意义的名称,便于调试");
System.out.println(" - 例如: pool-1-thread-1, worker-1, producer, consumer");
System.out.println(" - 可使用ThreadFactory定制命名");
System.out.println();
}
}
2.2 线程的生命周期
2.2.1 线程状态
public class ThreadLifecycleDemo {
public static void main(String[] args) throws InterruptedException {
System.out.println("=== 线程生命周期 ===\n");
demonstrateStates();
stateTransitions();
}
private static void demonstrateStates() throws InterruptedException {
System.out.println("【线程状态演示】\n");
Thread thread = new Thread(() -> {
try {
System.out.println("状态: " + Thread.currentThread().getState());
Thread.sleep(100);
synchronized (ThreadLifecycleDemo.class) {
ThreadLifecycleDemo.class.wait(50);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
System.out.println("创建后状态: " + thread.getState());
thread.start();
System.out.println("启动后状态: " + thread.getState());
Thread.sleep(10);
thread.join();
System.out.println("结束后状态: " + thread.getState());
System.out.println();
}
private static void stateTransitions() {
System.out.println("【状态转换详解】\n");
System.out.println("1. NEW (新建)");
System.out.println(" - 线程刚创建,尚未启动");
System.out.println(" - 调用start()后变为RUNNABLE");
System.out.println();
System.out.println("2. RUNNABLE (可运行)");
System.out.println(" - 包括就绪(Ready)和运行中(Running)");
System.out.println(" - 可能正在执行,也可能等待CPU时间片");
System.out.println();
System.out.println("3. BLOCKED (阻塞)");
System.out.println(" - 等待获取监视器锁");
System.out.println(" - 进入synchronized块/方法");
System.out.println(" - 获取锁后变为RUNNABLE");
System.out.println();
System.out.println("4. WAITING (等待)");
System.out.println(" - 无限等待,需其他线程唤醒");
System.out.println(" - 触发方法:");
System.out.println(" - Object.wait()");
System.out.println(" - Thread.join()");
System.out.println(" - LockSupport.park()");
System.out.println();
System.out.println("5. TIMED_WAITING (超时等待)");
System.out.println(" - 有时限的等待");
System.out.println(" - 触发方法:");
System.out.println(" - Thread.sleep(time)");
System.out.println(" - Object.wait(time)");
System.out.println(" - Thread.join(time)");
System.out.println(" - LockSupport.parkNanos(time)");
System.out.println();
System.out.println("6. TERMINATED (终止)");
System.out.println(" - 线程执行完毕");
System.out.println(" - 或因异常退出");
System.out.println();
System.out.println("状态转换图:");
System.out.println("""
start()
NEW ─────────► RUNNABLE ◄─────────────────────┐
│ │
┌───────────┼───────────┐ │
│ │ │ │
▼ ▼ ▼ │
BLOCKED WAITING TIMED_WAITING │
│ │ │ │
└───────────┴───────────┴──────────────┘
│
▼
TERMINATED
""");
System.out.println();
}
}
class ThreadStateDemo {
private static final Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
System.out.println("=== 线程状态转换实例 ===\n");
demonstrateBlockedState();
demonstrateWaitingState();
demonstrateTimedWaitingState();
}
private static void demonstrateBlockedState() throws InterruptedException {
System.out.println("【BLOCKED状态演示】\n");
Thread t1 = new Thread(() -> {
synchronized (lock) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}, "Thread-1");
Thread t2 = new Thread(() -> {
synchronized (lock) {
}
}, "Thread-2");
t1.start();
Thread.sleep(100);
t2.start();
Thread.sleep(100);
System.out.println(t2.getName() + " 状态: " + t2.getState());
t1.join();
t2.join();
System.out.println();
}
private static void demonstrateWaitingState() throws InterruptedException {
System.out.println("【WAITING状态演示】\n");
Thread t = new Thread(() -> {
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}, "Waiting-Thread");
t.start();
Thread.sleep(100);
System.out.println(t.getName() + " 状态: " + t.getState());
synchronized (lock) {
lock.notify();
}
t.join();
System.out.println();
}
private static void demonstrateTimedWaitingState() throws InterruptedException {
System.out.println("【TIMED_WAITING状态演示】\n");
Thread t = new Thread(() -> {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}, "Sleeping-Thread");
t.start();
Thread.sleep(100);
System.out.println(t.getName() + " 状态: " + t.getState());
t.interrupt();
t.join();
System.out.println();
}
}
2.3 线程的基本操作
2.3.1 启动与停止
import java.util.concurrent.*;
public class ThreadStartStopDemo {
public static void main(String[] args) throws InterruptedException {
System.out.println("=== 线程启动与停止 ===\n");
startMethod();
stopMethod();
interruptMethod();
}
private static void startMethod() {
System.out.println("【start()方法】\n");
Thread t1 = new Thread(() -> {
System.out.println("执行线程: " + Thread.currentThread().getName());
});
t1.start();
System.out.println();
System.out.println("注意事项:");
System.out.println(" 1. 一个线程只能启动一次");
System.out.println(" 2. 重复调用start()会抛出IllegalThreadStateException");
System.out.println(" 3. 不要直接调用run()方法");
System.out.println();
}
private static void stopMethod() throws InterruptedException {
System.out.println("【停止线程的正确方式】\n");
System.out.println("❌ 已废弃的方法:");
System.out.println(" - stop(): 强制停止,不安全");
System.out.println(" - suspend(): 挂起线程,容易死锁");
System.out.println(" - resume(): 恢复线程");
System.out.println();
System.out.println("✅ 正确的停止方式:");
System.out.println(" 1. 使用volatile标志位");
System.out.println(" 2. 使用interrupt()中断");
System.out.println(" 3. 使用Future.cancel()");
System.out.println();
class StoppableTask implements Runnable {
private volatile boolean stopped = false;
@Override
public void run() {
while (!stopped && !Thread.currentThread().isInterrupted()) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
System.out.println("线程正常停止");
}
public void stop() {
stopped = true;
}
}
StoppableTask task = new StoppableTask();
Thread t = new Thread(task);
t.start();
Thread.sleep(500);
task.stop();
t.join();
System.out.println();
}
private static void interruptMethod() throws InterruptedException {
System.out.println("【interrupt()机制】\n");
Thread t = new Thread(() -> {
while (!Thread.currentThread().isInterrupted()) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
System.out.println("线程被中断");
Thread.currentThread().interrupt();
break;
}
}
System.out.println("线程响应中断并退出");
});
t.start();
Thread.sleep(300);
t.interrupt();
t.join();
System.out.println();
System.out.println("中断相关方法:");
System.out.println(" - interrupt(): 设置中断标志");
System.out.println(" - isInterrupted(): 检查中断标志(不清除)");
System.out.println(" - interrupted(): 检查并清除中断标志(静态方法)");
System.out.println();
System.out.println("响应中断的方法:");
System.out.println(" - Object.wait()");
System.out.println(" - Thread.join()");
System.out.println(" - Thread.sleep()");
System.out.println(" - BlockingQueue.put/take");
System.out.println(" - Lock.lockInterruptibly");
System.out.println();
}
}
class GracefulShutdownDemo {
public static void main(String[] args) throws InterruptedException {
System.out.println("=== 优雅停止线程 ===\n");
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<?> future = executor.submit(() -> {
while (!Thread.currentThread().isInterrupted()) {
try {
System.out.println("工作中...");
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println("收到中断信号,准备停止");
Thread.currentThread().interrupt();
break;
}
}
System.out.println("清理资源...");
});
Thread.sleep(2000);
future.cancel(true);
executor.shutdown();
executor.awaitTermination(5, TimeUnit.SECONDS);
System.out.println("线程池已关闭");
}
}
2.3.2 等待与通知
public class WaitNotifyDemo {
public static void main(String[] args) throws InterruptedException {
System.out.println("=== 线程等待与通知 ===\n");
waitNotifyDemo();
waitTimeoutDemo();
producerConsumerDemo();
}
private static void waitNotifyDemo() throws InterruptedException {
System.out.println("【wait/notify基础】\n");
Object lock = new Object();
Thread waitingThread = new Thread(() -> {
synchronized (lock) {
try {
System.out.println("等待线程: 开始等待");
lock.wait();
System.out.println("等待线程: 被唤醒");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
Thread notifyThread = new Thread(() -> {
synchronized (lock) {
try {
Thread.sleep(1000);
System.out.println("通知线程: 发送通知");
lock.notify();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
waitingThread.start();
Thread.sleep(100);
notifyThread.start();
waitingThread.join();
notifyThread.join();
System.out.println();
System.out.println("使用规范:");
System.out.println(" 1. 必须在synchronized块内调用");
System.out.println(" 2. wait()会释放锁,notify()不会释放锁");
System.out.println(" 3. 建议使用while循环检查条件");
System.out.println(" 4. 优先使用notifyAll()避免信号丢失");
System.out.println();
}
private static void waitTimeoutDemo() throws InterruptedException {
System.out.println("【超时等待】\n");
Object lock = new Object();
Thread t = new Thread(() -> {
synchronized (lock) {
try {
System.out.println("开始超时等待(2秒)");
long start = System.currentTimeMillis();
lock.wait(2000);
long elapsed = System.currentTimeMillis() - start;
System.out.println("等待结束,耗时: " + elapsed + "ms");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
t.start();
t.join();
System.out.println();
}
private static void producerConsumerDemo() throws InterruptedException {
System.out.println("【生产者-消费者模式】\n");
class BoundedBuffer<T> {
private final Object[] items;
private int putIndex, takeIndex, count;
public BoundedBuffer(int capacity) {
items = new Object[capacity];
}
@SuppressWarnings("unchecked")
public T take() throws InterruptedException {
synchronized (this) {
while (count == 0) {
System.out.println("缓冲区为空,消费者等待");
wait();
}
Object item = items[takeIndex];
items[takeIndex] = null;
takeIndex = (takeIndex + 1) % items.length;
count--;
notifyAll();
return (T) item;
}
}
public void put(T item) throws InterruptedException {
synchronized (this) {
while (count == items.length) {
System.out.println("缓冲区已满,生产者等待");
wait();
}
items[putIndex] = item;
putIndex = (putIndex + 1) % items.length;
count++;
System.out.println("生产: " + item);
notifyAll();
}
}
}
BoundedBuffer<String> buffer = new BoundedBuffer<>(3);
Thread producer = new Thread(() -> {
for (int i = 0; i < 5; i++) {
try {
buffer.put("Item-" + i);
Thread.sleep(200);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
Thread consumer = new Thread(() -> {
for (int i = 0; i < 5; i++) {
try {
String item = buffer.take();
System.out.println("消费: " + item);
Thread.sleep(500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
producer.start();
consumer.start();
producer.join();
consumer.join();
System.out.println();
}
}
2.3.3 join与yield
public class JoinYieldDemo {
public static void main(String[] args) throws InterruptedException {
System.out.println("=== join和yield ===\n");
joinDemo();
yieldDemo();
}
private static void joinDemo() throws InterruptedException {
System.out.println("【join方法】\n");
System.out.println("join(): 等待目标线程结束");
System.out.println("join(long): 超时等待");
System.out.println();
Thread t1 = new Thread(() -> {
try {
System.out.println("线程1开始执行");
Thread.sleep(2000);
System.out.println("线程1执行完毕");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
Thread t2 = new Thread(() -> {
try {
System.out.println("线程2开始执行");
Thread.sleep(1000);
System.out.println("线程2执行完毕");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
long start = System.currentTimeMillis();
t1.start();
t2.start();
System.out.println("主线程等待子线程完成...");
t1.join();
t2.join();
long elapsed = System.currentTimeMillis() - start;
System.out.println("所有子线程完成,耗时: " + elapsed + "ms");
System.out.println();
System.out.println("应用场景:");
System.out.println(" 1. 等待多个线程完成");
System.out.println(" 2. 线程间顺序控制");
System.out.println(" 3. 获取线程执行结果");
System.out.println();
}
private static void yieldDemo() {
System.out.println("【yield方法】\n");
System.out.println("yield(): 暗示调度器让出CPU时间片");
System.out.println();
Thread t1 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("线程1: " + i);
Thread.yield();
}
});
Thread t2 = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("线程2: " + i);
Thread.yield();
}
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println();
System.out.println("说明:");
System.out.println(" - yield只是建议,调度器可能忽略");
System.out.println(" - 从RUNNING变为RUNNABLE状态");
System.out.println(" - 可能让同优先级或更高优先级的线程执行");
System.out.println(" - 实际使用较少,可用于调试");
System.out.println();
}
}
2.4 守护线程
public class DaemonThreadDemo {
public static void main(String[] args) throws InterruptedException {
System.out.println("=== 守护线程 ===\n");
daemonDemo();
daemonUseCases();
}
private static void daemonDemo() throws InterruptedException {
System.out.println("【守护线程演示】\n");
Thread userThread = new Thread(() -> {
for (int i = 0; i < 5; i++) {
try {
System.out.println("用户线程运行: " + i);
Thread.sleep(500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
System.out.println("用户线程结束");
}, "User-Thread");
Thread daemonThread = new Thread(() -> {
int i = 0;
while (true) {
try {
System.out.println("守护线程运行: " + i++);
Thread.sleep(300);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
break;
}
}
System.out.println("守护线程结束");
}, "Daemon-Thread");
daemonThread.setDaemon(true);
System.out.println("用户线程是否为守护线程: " + userThread.isDaemon());
System.out.println("守护线程是否为守护线程: " + daemonThread.isDaemon());
System.out.println();
userThread.start();
daemonThread.start();
userThread.join();
System.out.println("\n用户线程结束,JVM即将退出");
System.out.println("守护线程也会随之结束(可能未完成)");
System.out.println();
}
private static void daemonUseCases() {
System.out.println("【守护线程应用场景】\n");
System.out.println("典型应用:");
System.out.println(" 1. GC线程 (垃圾回收)");
System.out.println(" 2. 后台监控线程");
System.out.println(" 3. 日志写入线程");
System.out.println(" 4. 缓存清理线程");
System.out.println();
System.out.println("注意事项:");
System.out.println(" 1. setDaemon()必须在start()前调用");
System.out.println(" 2. 守护线程创建的线程默认也是守护线程");
System.out.println(" 3. 不要在守护线程中访问共享资源(可能随时终止)");
System.out.println(" 4. 守护线程中的finally块不保证执行");
System.out.println();
System.out.println("【finally块示例】\n");
Thread daemonWithFinally = new Thread(() -> {
try {
System.out.println("守护线程: try块");
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
System.out.println("守护线程: finally块(可能不会执行)");
}
});
daemonWithFinally.setDaemon(true);
daemonWithFinally.start();
System.out.println("主线程即将结束");
}
}
2.5 线程优先级
public class ThreadPriorityDemo {
public static void main(String[] args) {
System.out.println("=== 线程优先级 ===\n");
priorityDemo();
priorityGuidelines();
}
private static void priorityDemo() {
System.out.println("【优先级范围】\n");
System.out.println("优先级范围: 1-10");
System.out.println(" - MIN_PRIORITY = 1");
System.out.println(" - NORM_PRIORITY = 5 (默认)");
System.out.println(" - MAX_PRIORITY = 10");
System.out.println();
Thread lowPriority = new Thread(() -> {
int count = 0;
while (count < 10000) {
count++;
}
System.out.println("低优先级线程完成: " + count);
}, "Low-Priority");
lowPriority.setPriority(Thread.MIN_PRIORITY);
Thread highPriority = new Thread(() -> {
int count = 0;
while (count < 10000) {
count++;
}
System.out.println("高优先级线程完成: " + count);
}, "High-Priority");
highPriority.setPriority(Thread.MAX_PRIORITY);
highPriority.start();
lowPriority.start();
System.out.println();
System.out.println("说明:");
System.out.println(" - 优先级只是建议,实际调度取决于操作系统");
System.out.println(" - 不同操作系统实现不同");
System.out.println(" - 高优先级线程获得CPU时间的概率更高");
System.out.println(" - 但不保证执行顺序");
System.out.println();
}
private static void priorityGuidelines() {
System.out.println("【优先级使用建议】\n");
System.out.println("❌ 不推荐:");
System.out.println(" - 依赖优先级控制程序逻辑");
System.out.println(" - 频繁修改优先级");
System.out.println(" - 假设优先级能保证执行顺序");
System.out.println();
System.out.println("✅ 推荐做法:");
System.out.println(" - 使用默认优先级");
System.out.println(" - 通过任务队列控制执行顺序");
System.out.println(" - 使用线程池管理线程");
System.out.println(" - 让操作系统调度器决定");
System.out.println();
}
}
三、可运行Java代码示例
完整示例:多线程协作
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class ThreadCoordinationDemo {
public static void main(String[] args) throws InterruptedException {
System.out.println("=== 多线程协作示例 ===\n");
parallelComputation();
phasedTask();
threadCommunication();
}
private static void parallelComputation() throws InterruptedException {
System.out.println("【并行计算】\n");
int[] array = new int[1000000];
for (int i = 0; i < array.length; i++) {
array[i] = i + 1;
}
int threadCount = 4;
AtomicInteger totalSum = new AtomicInteger(0);
CountDownLatch latch = new CountDownLatch(threadCount);
int chunkSize = array.length / threadCount;
long start = System.currentTimeMillis();
for (int i = 0; i < threadCount; i++) {
final int startIdx = i * chunkSize;
final int endIdx = (i == threadCount - 1) ? array.length : startIdx + chunkSize;
new Thread(() -> {
int sum = 0;
for (int j = startIdx; j < endIdx; j++) {
sum += array[j];
}
totalSum.addAndGet(sum);
latch.countDown();
}, "Calculator-" + i).start();
}
latch.await();
long elapsed = System.currentTimeMillis() - start;
System.out.println("并行计算结果: " + totalSum.get());
System.out.println("耗时: " + elapsed + "ms");
start = System.currentTimeMillis();
long singleThreadSum = 0;
for (int value : array) {
singleThreadSum += value;
}
elapsed = System.currentTimeMillis() - start;
System.out.println("单线程结果: " + singleThreadSum);
System.out.println("单线程耗时: " + elapsed + "ms");
System.out.println();
}
private static void phasedTask() throws InterruptedException {
System.out.println("【阶段性任务】\n");
CyclicBarrier barrier = new CyclicBarrier(3, () -> {
System.out.println("=== 阶段完成 ===\n");
});
for (int i = 0; i < 3; i++) {
final int taskId = i;
new Thread(() -> {
try {
System.out.println("任务" + taskId + ": 阶段1执行");
Thread.sleep((long) (Math.random() * 1000));
barrier.await();
System.out.println("任务" + taskId + ": 阶段2执行");
Thread.sleep((long) (Math.random() * 1000));
barrier.await();
System.out.println("任务" + taskId + ": 阶段3执行");
} catch (Exception e) {
Thread.currentThread().interrupt();
}
}, "Task-" + i).start();
}
Thread.sleep(3000);
System.out.println();
}
private static void threadCommunication() throws InterruptedException {
System.out.println("【线程间通信】\n");
BlockingQueue<String> queue = new ArrayBlockingQueue<>(5);
AtomicInteger producedCount = new AtomicInteger(0);
AtomicInteger consumedCount = new AtomicInteger(0);
Thread producer = new Thread(() -> {
try {
for (int i = 0; i < 10; i++) {
String item = "Item-" + i;
queue.put(item);
producedCount.incrementAndGet();
System.out.println("生产: " + item + " (队列大小: " + queue.size() + ")");
Thread.sleep(100);
}
queue.put("END");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}, "Producer");
Thread consumer = new Thread(() -> {
try {
while (true) {
String item = queue.take();
if ("END".equals(item)) {
break;
}
consumedCount.incrementAndGet();
System.out.println("消费: " + item + " (队列大小: " + queue.size() + ")");
Thread.sleep(150);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}, "Consumer");
producer.start();
consumer.start();
producer.join();
consumer.join();
System.out.println("\n生产总数: " + producedCount.get());
System.out.println("消费总数: " + consumedCount.get());
System.out.println();
}
}
四、总结与最佳实践
核心要点回顾
| 分类 | 内容 |
|---|
| 创建方式 | 继承Thread、实现Runnable、实现Callable |
| 线程状态 | NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED |
| 基本操作 | start、interrupt、join、yield、sleep、wait/notify |
| 守护线程 | 后台服务线程,随用户线程结束而终止 |
最佳实践
public class ThreadBestPractices {
public static void main(String[] args) {
System.out.println("=== 线程最佳实践 ===\n");
System.out.println("1. 命名规范");
System.out.println(" - 使用有意义的线程名称");
System.out.println(" - 便于调试和监控");
System.out.println(" Thread t = new Thread(task, 'worker-thread-1');");
System.out.println();
System.out.println("2. 正确停止线程");
System.out.println(" - 使用interrupt()而不是stop()");
System.out.println(" - 检查中断标志");
System.out.println(" - 正确处理InterruptedException");
System.out.println();
System.out.println("3. 使用线程池");
System.out.println(" - 避免频繁创建销毁线程");
System.out.println(" - 控制并发数量");
System.out.println(" - ExecutorService executor = Executors.newFixedThreadPool(10);");
System.out.println();
System.out.println("4. 异常处理");
System.out.println(" - 设置UncaughtExceptionHandler");
System.out.println(" - 记录异常日志");
System.out.println();
System.out.println("5. 资源管理");
System.out.println(" - 使用try-with-resources");
System.out.println(" - finally块中释放资源");
System.out.println();
System.out.println("6. 避免死锁");
System.out.println(" - 固定加锁顺序");
System.out.println(" - 使用超时锁");
System.out.println(" - 减小锁粒度");
System.out.println();
Thread t = new Thread(() -> {
throw new RuntimeException("测试异常");
});
t.setName("Exception-Thread");
t.setUncaughtExceptionHandler((thread, throwable) -> {
System.err.println("线程 " + thread.getName() + " 发生异常: " + throwable.getMessage());
});
t.start();
try {
t.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
常见陷阱
public class ThreadPitfalls {
public static void main(String[] args) {
System.out.println("=== 线程常见陷阱 ===\n");
System.out.println("1. 直接调用run()而不是start()");
System.out.println(" ❌ thread.run(); // 不会创建新线程");
System.out.println(" ✅ thread.start(); // 创建新线程");
System.out.println();
System.out.println("2. 重复调用start()");
System.out.println(" ❌ thread.start(); thread.start(); // 抛异常");
System.out.println();
System.out.println("3. 在构造函数中启动线程");
System.out.println(" ❌ this引用可能泄露");
System.out.println(" ✅ 使用工厂方法或Builder");
System.out.println();
System.out.println("4. 忽略InterruptedException");
System.out.println(" ❌ catch (InterruptedException e) {} // 吞掉异常");
System.out.println(" ✅ catch (InterruptedException e) { Thread.currentThread().interrupt(); }");
System.out.println();
System.out.println("5. wait()不在循环中");
System.out.println(" ❌ if (condition) { wait(); }");
System.out.println(" ✅ while (condition) { wait(); }");
System.out.println();
System.out.println("6. 在守护线程中操作共享资源");
System.out.println(" 守护线程随时可能终止,数据可能不完整");
System.out.println();
System.out.println("7. 过度同步");
System.out.println(" - 导致性能问题");
System.out.println(" - 可能死锁");
System.out.println(" - 保持同步块短小");
System.out.println();
}
}
相关工具类
| 工具类 | 用途 |
|---|
| CountDownLatch | 一次性门闩,等待多线程完成 |
| CyclicBarrier | 循环栅栏,多线程同步点 |
| Semaphore | 信号量,控制并发数 |
| Exchanger | 线程间数据交换 |
| Phaser | 阶段同步器 |
扩展阅读
- 《Java并发编程实战》:并发编程经典
- 《Java并发编程的艺术》:深入原理
- JDK文档:Thread类、java.util.concurrent包