Files
2026-06-19 14:45:07 +08:00

4.4 KiB

title, date, category, tags, excerpt
title date category tags excerpt
Java 并发编程完整指南:从线程基础到 JUC 进阶 2026-05-26 后端开发
Java
并发
JUC
全面梳理 Java 并发编程知识体系,从线程基础、synchronized 原理到 JUC 并发工具类。

一、线程基础知识

1.1 线程的生命周期

Java 线程在它的生命周期中会经历六种状态:

  • NEW — 线程刚创建,尚未调用 start()
  • RUNNABLE — 线程在 JVM 中运行
  • BLOCKED — 线程被阻塞,等待获取锁
  • WAITING — 无限期等待
  • TIMED_WAITING — 超时等待
  • TERMINATED — 线程已执行完毕

重要区别:BLOCKED 是在等待进入 synchronized 块时发生的,而 WAITING 是通过 Object.wait()、Thread.join() 等方法进入的。

1.2 线程的创建方式

Java 中创建线程主要有四种方式:

继承 Thread 类

class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("线程运行中: " + Thread.currentThread().getName());
    }
}
MyThread thread = new MyThread();
thread.start();

实现 Runnable 接口

class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("线程运行中");
    }
}
Thread thread = new Thread(new MyRunnable());
thread.start();

Callable 与 Future

class MyCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        Thread.sleep(1000);
        return "任务完成";
    }
}
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new MyCallable());
String result = future.get();

二、synchronized 原理

2.1 对象头与 Monitor

Java 中的每个对象都与一个 Monitor 关联。synchronized 关键字的底层实现依赖于对象头中的 Mark Word 和 Monitor 机制。

  • Mark Word:存储对象的 HashCode、GC 分代年龄、锁状态标志
  • Monitor:包含 EntryList、WaitSet、Owner 三个关键部分
public class Counter {
    private int count = 0;
    
    public synchronized void increment() {
        count++;
    }
    
    public void incrementWithBlock() {
        synchronized (this) {
            count++;
        }
    }
}

2.2 锁升级过程

JDK 1.6 之后,锁不再直接膨胀为重量级锁,而是逐步升级:

锁状态 适用场景 实现原理
偏向锁 只有一个线程访问 Mark Word 记录线程 ID
轻量级锁 多线程交替执行 CAS + 自旋
重量级锁 竞争激烈 OS Mutex Lock

三、JUC 并发工具

3.1 ReentrantLock

比 synchronized 更灵活的锁实现:

ReentrantLock lock = new ReentrantLock(true);
lock.lock();
try {
    // 临界区代码
} finally {
    lock.unlock();
}

3.2 CountDownLatch

等待其他线程完成操作:

CountDownLatch latch = new CountDownLatch(3);
for (int i = 0; i < 3; i++) {
    new Thread(() -> {
        // 执行任务...
        latch.countDown();
    }).start();
}
latch.await();

3.3 Semaphore

控制同时访问资源的线程数量:

Semaphore semaphore = new Semaphore(5);
semaphore.acquire();
try {
    // 最多5个线程同时执行
} finally {
    semaphore.release();
}

四、线程池原理

4.1 核心参数

public ThreadPoolExecutor(
    int corePoolSize,      // 核心线程数
    int maximumPoolSize,   // 最大线程数
    long keepAliveTime,    // 空闲线程存活时间
    TimeUnit unit,         
    BlockingQueue<Runnable> workQueue, 
    ThreadFactory threadFactory,       
    RejectedExecutionHandler handler   
)

工作流程:核心线程 → 任务队列 → 最大线程 → 拒绝策略

4.2 拒绝策略

  • AbortPolicy — 抛出异常
  • CallerRunsPolicy — 由提交线程自己执行
  • DiscardPolicy — 静默丢弃
  • DiscardOldestPolicy — 丢弃最早的未处理任务

五、虚拟线程

Java 21 正式引入了虚拟线程:

Thread vThread = Thread.ofVirtual()
    .name("virtual-thread-1")
    .start(() -> {
        System.out.println("虚拟线程运行中");
    });

传统"一个请求一个线程"模式在虚拟线程诞生后变得不再昂贵。对于 IO 密集型应用,虚拟线程可以显著提升吞吐量。