JUC - 文章目录

up

返回上级

sourcecode/java 上一级目录
md

AbstractQueuedSynchronizer

写一个锁,难点从来不在"改个标志位",而在抢不到时的排队、阻塞、唤醒、取消这套脏活。[AQS](/articles/java原理/juc/juc/82juc原理/1aqs/) 把脏活做成模板:框架只管"一个 volatile int state + 一条 CLH 变体的 FIFO 队列",子类只需用 state 定义"什么算抢到、什么算放掉"(tryAcqu

#JUC
md

ArrayBlockingQueue

数组实现的有界阻塞队列:一把 ReentrantLock 管住全部读写,配 notEmpty/notFull 两个条件队列,队满 put 挂起、队空 take 挂起。它是生产者消费者模型的教科书实现,也是线程池 workQueue 的常见选择。

#JUC
md

AtomicInteger

无锁的原子 int:i++ 这种"读改写"复合操作靠 CPU 的 CAS/fetchandadd 指令一步完成,不加锁也线程安全。整个类几乎没有逻辑,全是往 Unsafe 上转发——真正值得看的是它怎么定位内存、怎么自旋、以及 JIT 怎么把自旋整个优化掉。

#JUC
md

CountDownLatch

一次性的"倒计时门闩":初始化计数 N,各线程 countDown() 减一,await() 的线程阻塞到计数归零后全部放行。 核心思路是把 AQS 的 state 直接当计数用——归零即开门,且是永久开门,不能重置(要循环用的场景是 CyclicBarrier 的地盘)。 整个类不到 60 行有效代码,是 AQS 共享模式最干净的教科书用法。

#JUC
md

CyclicBarrier

可循环的"栅栏": N 个线程互相等待, 都到齐了才一起放行, 放行后自动复位可再用。它不走 AQS 共享模式, 而是用一把 ReentrantLock + 一个 Condition 把"计数、回调、唤醒"全部收进临界区, 再用一个 Generation 对象标识"第几轮", 换代即放行。

#JUC
md

FutureTask

FutureTask 是"一次异步计算"的结果容器:把 Callable 包装成可以丢给线程执行的任务,调用方随时 get() 阻塞取结果、cancel() 取消。 它不用锁,核心是一个 volatile int state 状态机——CAS 保证结果只发布一次,Treiber 栈(无锁链栈)挂起等结果的线程。 [线程池](/articles/qa/旁生枝茎

#JUC
md

LinkedBlockingQueue

链表实现的阻塞队列, 解决的问题和 [ArrayBlockingQueue](/articles/sourcecode/java/juc/arrayblockingqueue/) 一样(生产者消费者), 但它把"入队"和"出队"拆成两把独立的锁: put 只碰尾巴, take 只碰头, 两边可以真正并行。 能这么拆的前提是一个 AtomicInteger c

#JUC
md

LockSupport

线程阻塞/唤醒的最底层积木:AQS、ReentrantLock、Semaphore 里所有"排队睡觉"的动作最终都落到这里的 park/unpark。核心思路是给每个线程配一张"许可"(permit):unpark 发许可(最多攒一张),park 消费许可,有就立刻返回,没有才真正挂起——顺序无关,谁先到都不丢唤醒。

#JUC
md

LongAdder

AtomicLong 在高并发写入时, 所有线程挤在同一个 long 上 [CAS](/articles/qa/旁生枝茎/cas/) 自旋, 失败重试白烧 CPU。 LongAdder 把"一个热点"拆成"base + 一张 Cell 表": 没竞争时只写 base, 有竞争就按线程哈希散到不同 Cell 上各写各的, 读的时候再把 base 和所有 Cel

#JUC
md

ReentrantLock

ReentrantLock 解决的问题:给 Java 一把比 [synchronized](/articles/java原理/juc/juc/2并发之共享模型/3synchronized原理/) 更可控的独占锁,可中断、可超时、可公平、可挂多个条件队列。 核心思路:锁本身只是门面,全部同步逻辑委托给 [AQS](/articles/java原理/juc/ju

#JUC
md

ReentrantReadWriteLock · JUC

读多写少的场景下,独占锁把互不冲突的读线程也串行化了。ReentrantReadWriteLock 用 AQS 的一个 state 同时管两把锁:读锁共享、写锁独占,写锁还能"降级"成读锁。核心技巧是把 state 按位切成两半,一次 CAS 同时维护读写两个计数。

#JUC
md

ScheduledThreadPoolExecutor

定时/周期任务[线程池](/articles/qa/旁生枝茎/线程池/),Timer 的替代品(Timer 单线程、任务抛异常整个定时器死掉)。 核心思路:继承 ThreadPoolExecutor,把工作队列换成按触发时间排序的二叉小顶堆 DelayedWorkQueue,任务包装成带 time/period 的 ScheduledFutureTask,周

#JUC
md

Semaphore

Semaphore 解决的问题:限制同时进入某段代码/某个资源的线程数量(比如"这个接口最多 10 个并发")。 核心思路是维护一个许可计数,acquire 扣一个(不够就排队阻塞),release 还一个——许可不是对象,只是 AQS 里的一个 int:state = 剩余许可数。 整个类没有一行阻塞代码,排队、挂起、唤醒全部委托给 AQS 的共享模式。

#JUC
md

ThreadLocal

ThreadLocal 让每个线程持有同一个变量的独立副本,互不干扰,常用于存用户上下文、数据库连接、SimpleDateFormat 这类线程不安全对象。 核心思路是存储倒置:值并不放在 ThreadLocal 里,而是放在每个 Thread 自带的 ThreadLocalMap 中,ThreadLocal 实例只充当查这张表的 key。这样线程只读写自己

#JUC
md

ThreadPoolExecutor · JUC

线程池解决两个问题:线程创建销毁开销大,以及无节制开线程会耗尽系统资源。ThreadPoolExecutor 的思路是让固定的一批 worker 线程循环消费同一个阻塞队列,把"提交任务"和"执行任务"解耦;整个池子的生命周期状态和线程数被压进一个 AtomicInteger(ctl),靠位运算拆装。

#JUC