首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >这些常见的JUC八股,你能答出来多少?

这些常见的JUC八股,你能答出来多少?

作者头像
Ynchen
发布2025-12-21 13:33:05
发布2025-12-21 13:33:05
4130
举报

1. 线程 vs 进程

区别:

  • 进程
    • 系统资源分配的最小单元
    • 独立内存空间,隔离性、安全性高
    • 创建/切换开销大
    • 一个进程崩溃不会影响其他进程
  • 线程
    • CPU 调度的最小单元
    • 共享进程内存空间,创建/切换开销小
    • 安全性较低,易引发共享资源冲突
    • 一个线程崩溃可能导致整个进程崩溃

创建线程方式:

  • 继承 Thread
  • 实现 Runnable
  • 实现 Callable
  • 线程池
  • CompletableFuture

2. 死锁

出现条件(4 个必要条件):

  1. 互斥
  2. 占有并等待
  3. 不可剥夺
  4. 循环等待

解决案例:

  • 排查定位
    • jstack 导出线程堆栈 → 找到 Found one Java-level deadlock
    • 分析日志 & 锁获取顺序
  • 修复优化
    • 统一加锁顺序
    • tryLock(timeout) 防止长时间阻塞
    • 数据库事务加锁顺序统一
  • 预防措施
    • 全局加锁顺序约定文档
    • 锁加 TTL
    • 开发/测试引入死锁检测工具(Arthas、ThreadMXBean)

3. 乐观锁 vs 悲观锁

  • 乐观锁: 不加锁,操作时校验数据是否被修改(版本号/时间戳),冲突时回滚。
  • 悲观锁: 操作前直接加锁,保证同一时间只有一个线程操作资源。

4. CAS

  • Compare And Swap:比较内存值与期望值,相同则更新,否则自旋重试
  • 缺点
    • 高并发下自旋消耗 CPU
    • ABA 问题(可用版本号解决)

5. synchronized vs ReentrantLock

synchronized

  • JVM 关键字 → monitorenter / monitorexit
  • 依赖对象监视器锁(Mark Word)
  • 锁升级机制:无锁 → 偏向锁 → 轻量级锁 → 重量级锁
  • 可重入、非公平、不可中断
  • 自动释放锁
  • 单一条件队列(wait/notify

ReentrantLock

  • API 层锁类,基于 AQS
  • 可重入、公平/非公平可选
  • 可中断、可超时获取
  • 多个条件队列(Condition
  • 必须手动释放锁(finally

6. AQS

  • 原理
    • 基于 volatile state + FIFO CLH 队列
    • 统一封装线程排队、阻塞、唤醒机制
  • 公平锁:获取锁前检查队列(hasQueuedPredecessors) → 先来先得
  • 非公平锁:直接 CAS 抢锁,可能插队

7. synchronized 锁升级流程

  1. 无锁
  2. 偏向锁(记录线程 ID,下次同线程直接获得锁)
  3. 轻量级锁(CAS 自旋)
  4. 重量级锁(阻塞,OS 互斥量)

可重入锁意义:避免同一线程多次加锁导致自死锁。


8. 线程池

核心参数:

  • corePoolSize
  • maximumPoolSize
  • keepAliveTime & TimeUnit
  • workQueue
  • threadFactory
  • rejectionHandler

任务提交流程:

  1. 小于核心线程数 → 创建核心线程
  2. ≥ 核心线程数 → 任务入队
  3. 队列满 → 创建非核心线程
  4. 线程数 = 最大值 → 执行拒绝策略

拒绝策略:

  1. AbortPolicy(抛异常)
  2. DiscardPolicy(直接丢弃)
  3. CallerRunsPolicy(调用者线程执行)
  4. DiscardOldestPolicy(丢弃队列最老任务)

线程数计算:

  • CPU 密集型:CPU 核数 + 1
  • IO 密集型:CPU 核数 * 2CPU 核数 / (1 - 阻塞系数)

9. 原子类

  • 基于 CAS(JDK8 用 Unsafe,JDK9+ 用 VarHandle
  • 无锁高性能,但有 ABA 问题(用带版本号原子类解决)

10. volatile

  • 作用
    1. 可见性(修改立即对其他线程可见)
    2. 禁止指令重排序(通过内存屏障)
  • 不能保证原子性

11. JMM & happens-before

JMM:线程通过主内存共享变量,每个线程有本地工作内存。 指令重排序:编译器 & CPU 为优化会调整执行顺序(不影响单线程语义)。

happens-before 规则:

  1. 程序次序
  2. 锁(解锁 → 加锁)
  3. volatile(写 → 读)
  4. 线程启动(start() → 线程内操作)
  5. 线程终止(线程内操作 → join() 返回)
  6. 传递性
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-12-12,如有侵权请联系 cloudcommunity@tencent.com 删除
目录
  • 1. 线程 vs 进程
  • 2. 死锁
  • 3. 乐观锁 vs 悲观锁
  • 4. CAS
  • 5. synchronized vs ReentrantLock
  • 6. AQS
  • 7. synchronized 锁升级流程
  • 8. 线程池
  • 9. 原子类
  • 10. volatile
  • 11. JMM & happens-before
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档