返回首页

Java 中的线程:架构和同步

这篇文章从硬件处理器级别到 JVM 剖析 Java 中线程的结构。描述同步机制、Race Condition、Deadlock、Livelock 问题以及异步 CompletableFuture,用于高效开发。

Java 多线程:从 CPU 核心到 Deadlock
Advertisement 728x90

Java 线程架构与同步:从 CPU 到 JVM

Java 代码编译成字节码,由 JVM 转换为处理器可执行的机器指令。每颗 CPU 核心按顺序执行指令:寄存器中的位移操作等简单指令仅需一个时钟周期完成。寄存器是超高速存储单元,用于存放数字、地址和数据。

现代处理器采用超标量架构。超线程技术让单个硬件线程每周期执行 2–6 条指令,通过快速上下文切换,在每颗核心上模拟多个逻辑线程。

同时运行的线程数受核心数量限制。线程共享堆内存存储对象,每个线程有独立的栈来保存局部变量和对象引用。

Google AdInline article slot

竞态条件与内存结构

竞态条件发生在多个线程同时读写同一堆对象时,结果不可预测,取决于读-改-写操作的顺序。

代码在本地无负载时往往运行正常,但在生产环境的多线程负载下,冲突会不定期出现。操作系统进程分配共享内存;其中的线程是轻量级执行单元,竞争资源。

同步机制:wait/notify 和监视器

每个 Java 对象内置一个监视器(锁)。synchronized 块获取对象的监视器,确保:

Google AdInline article slot
  • 互斥性:仅一个线程执行块内代码。
  • 可见性:退出块后变更对其他线程可见(结合 volatile 支持)。

监视器包含:

  • 入口集:等待获取的线程队列。
  • 等待集:处于等待状态的线程。

wait()notify()notifyAll() 仅在同一对象的 synchronized 块内有效,否则抛出 IllegalMonitorStateException

  • wait():将线程移入等待集。
  • notify():唤醒一个随机线程(有唤醒丢失风险)。
  • notifyAll():唤醒所有线程(推荐做法)。

静态 synchronized 方法锁定类监视器(Class),不与实例方法(this)冲突。

Google AdInline article slot

高级锁机制:ReentrantLock 和 Semaphore

需要更多控制时,使用 java.util.concurrent.locks.ReentrantLock

Lock lock = new ReentrantLock();
lock.lock();
try {
    // 关键区
} finally {
    lock.unlock();
}

关键方法:

  • tryLock():非阻塞获取(失败返回 false)。
  • tryLock(timeout, unit):带超时的等待。
  • lockInterruptibly():可中断获取。
  • new ReentrantLock(true):公平锁(FIFO 顺序,稍慢)。

Semaphore 限制并发访问:

Semaphore sem = new Semaphore(3); // 3 个许可
sem.acquire(); // 获取
sem.release(); // 释放

多线程陷阱:死锁与活锁

死锁:循环锁依赖。线程 A 持有锁1 等待锁2;线程 B 反之。系统卡死。

避免方法:

  • 固定锁顺序。
  • 使用超时。
  • 最小化嵌套锁。

活锁:线程忙碌但无进展。例如:两个线程礼貌地互相让出资源,形成循环,CPU 飙升却无前进一步。

线程中的同步与异步

同步方法在 I/O 操作(如数据库查询)时阻塞线程:线程空闲等待响应。

异步使用 CompletableFuture——延迟结果容器(待定、完成或失败)。

操作链:

  • thenApply():转换结果。
  • thenCompose():与其他 Future 组合。
  • thenAccept():消费无返回值。
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "result")
    .thenApply(s -> s.toUpperCase())
    .thenAccept(System.out::println);

这释放线程处理其他任务,提升多线程环境吞吐量。

关键要点

  • 每核心运行一个硬件线程;超线程模拟多个。
  • 竞态条件源于共享堆;同步确保互斥与可见性。
  • 优先 notifyAll() 避免唤醒丢失。
  • ReentrantLock 扩展 synchronized,支持超时、中断与公平性。
  • CompletableFuture 实现无阻塞异步流水线。

— Editorial Team

Advertisement 728x90

继续阅读