一、JUC 核心概念解析

JUC 是 Java Util Concurrent 的缩写,是 Java 5 开始提供的并发编程工具包。它像一把瑞士军刀,提供了比传统 synchronized 更灵活的并发控制手段。

1.1 核心组件构成

在这里插入图片描述

1.2 与传统同步对比
// 传统方式
synchronized(obj) {
    // 临界区代码
}

// JUC方式
Lock lock = new ReentrantLock();
lock.lock();
try {
    // 临界区代码
} finally {
    lock.unlock();
}

关键差异

  • 可中断锁(避免死锁)
  • 公平锁机制
  • 多条件变量(Condition)
  • 锁等待超时功能

二、核心组件详解

2.1 Lock 体系

ReentrantLock 就像更智能的门禁系统:

Lock lock = new ReentrantLock(true); // 公平锁
Condition notEmpty = lock.newCondition();

public void consume() {
    lock.lock();
    try {
        while(queue.isEmpty()) {
            notEmpty.await(); // 精准等待
        }
        // 消费数据...
    } finally {
        lock.unlock();
    }
}
2.2 原子类原理(CAS 机制)

使用 CPU 级别的 Compare-And-Swap 指令:

AtomicInteger count = new AtomicInteger(0);

// 线程安全的自增
count.incrementAndGet();

CAS 流程图

线程 内存 读取当前值V 计算新值V' 比较并交换(V, V') 更新成功 更新失败 alt [值未改变] [值已改变] 线程 内存

三、典型应用场景

3.1 高并发计数器
// 错误示范(普通变量)
private int count = 0;

// 正确方案
private AtomicInteger count = new AtomicInteger(0);

public void safeIncrement() {
    count.incrementAndGet();
}
3.2 资源池管理(Semaphore)

像高速公路收费站:

Semaphore semaphore = new Semaphore(5); // 5个许可

void useResource() {
    semaphore.acquire();
    try {
        // 使用共享资源
    } finally {
        semaphore.release();
    }
}

四、常见面试题精解

题目:AQS(AbstractQueuedSynchronizer)工作原理?

解析

  1. 核心数据结构:CLH 队列(双向链表)
  2. 状态变量:volatile int state
  3. 关键方法:
    • acquire():获取资源
    • release():释放资源

类比说明
想象医院挂号系统:

  • state 表示剩余号源数
  • CLH 队列是排队患者
  • CAS 操作是自动叫号系统

五、思维导图生成

JUC 全称是 Java Util Concurrent,是 Java 并发编程的核心工具包,包含三大核心内容:


一、JUC 核心组件

  1. Lock 体系

    • ReentrantLock 显式锁(对标 synchronized
    Lock lock = new ReentrantLock();
    lock.lock();
    try {
        // 临界区
    } finally {
        lock.unlock();
    }
    
    • ReadWriteLock 读写分离锁(提升并发读性能)
  2. 原子类

    • AtomicInteger/AtomicReference 等(基于 CAS 的无锁并发)
    AtomicInteger count = new AtomicInteger(0);
    count.incrementAndGet();  // 线程安全的自增操作
    
  3. 并发集合

    • ConcurrentHashMap(分段锁实现)
    • CopyOnWriteArrayList(写时复制集合)
  4. 线程池

    • ThreadPoolExecutor 核心线程池实现
    • Executors 工厂类(但生产环境慎用)
  5. 同步工具

    • CountDownLatch(倒计时门闩)
    • CyclicBarrier(循环栅栏)
    • Semaphore(信号量)

二、实现原理

  1. AQS(AbstractQueuedSynchronizer)

    AQS 核心
    state 状态变量
    CLH 队列
    Node 节点存储线程
    • 通过 state 变量 + CLH 队列实现锁机制
  2. CAS(Compare And Swap)

    • CPU 原子指令实现无锁更新(sun.misc.Unsafe 类)
  3. 内存屏障

    • volatile 关键字保证可见性
    • happens-before 原则确保指令顺序

三、生产案例

  1. 电商库存扣减

    // 使用 AtomicInteger 保证库存扣减原子性
    AtomicInteger stock = new AtomicInteger(100);
    public boolean reduceStock() {
        while (true) {
            int current = stock.get();
            if (current <= 0) return false;
            if (stock.compareAndSet(current, current-1)) {
                return true;
            }
        }
    }
    
  2. 秒杀系统限流

    // 使用 Semaphore 控制并发数
    Semaphore semaphore = new Semaphore(500); // 允许 500 并发
    public void seckill() {
        if (!semaphore.tryAcquire()) {
            throw new RuntimeException("秒杀已满");
        }
        try {
            // 处理秒杀逻辑
        } finally {
            semaphore.release();
        }
    }
    

四、注意事项

  1. 死锁预防

    • 避免嵌套锁
    • 使用 tryLock() 设置超时时间
  2. 性能调优

    • 合理设置线程池参数(核心/最大线程数、队列类型)
    • 优先使用并发集合替代同步集合
  3. 线程安全设计

    • 状态变量尽量使用 final 修饰
    • 优先使用不可变对象

知识图谱

Java面试题解析:JUC详解

一、什么是JUC?

JUC是java.util.concurrent工具包的简称,是Java 5开始引入的并发编程工具包,包含:

  • 原子类(AtomicInteger等)
  • 并发集合(ConcurrentHashMap等)
  • 锁机制(ReentrantLock等)
  • 线程池(ThreadPoolExecutor等)
  • 同步工具(CountDownLatch等)

案例:传统售票问题

// 线程不安全的实现
class Ticket {
    private int count = 100;
    public void sell() {
        if(count > 0) {
            System.out.println(Thread.currentThread().getName() + "卖出票号" + count--);
        }
    }
}
// 使用JUC改进
class SafeTicket {
    private AtomicInteger count = new AtomicInteger(100);
    private ReentrantLock lock = new ReentrantLock();
    
    public void sell() {
        lock.lock();
        try {
            if(count.get() > 0) {
                System.out.println(Thread.currentThread().getName() + "卖出票号" + count.getAndDecrement());
            }
        } finally {
            lock.unlock();
        }
    }
}

二、核心组件解析

1. Lock体系

  • ReentrantLock vs synchronized
    • 可中断锁
    • 尝试获取锁(tryLock)
    • 公平锁/非公平锁

2. 原子类原理

CAS机制(Compare And Swap):

public final int getAndIncrement() {
    int prev, next;
    do {
        prev = get();         // 当前值
        next = prev + 1;      // 期望值
    } while (!compareAndSet(prev, next));
    return prev;
}

3. 线程池参数

核心参数
corePoolSize
maximumPoolSize
keepAliveTime
workQueue
ArrayBlockingQueue
LinkedBlockingQueue
SynchronousQueue

三、高频面试问题

  1. AQS原理:通过CLH队列管理线程,state变量控制资源状态
  2. ThreadLocal内存泄漏:使用弱引用+及时remove
  3. ConcurrentHashMap实现:JDK7分段锁 vs JDK8 CAS+synchronized
  4. 死锁排查:jstack查看线程状态

四、最佳实践建议

  1. 优先使用并发集合而非同步集合
  2. 使用ThreadPoolExecutor而非Executors创建线程池
  3. 合理设置锁粒度(如读写锁分离)
  4. 使用CompletableFuture处理异步任务

JUC知识体系总结

在这里插入图片描述

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐