Skip to content

Commit c11ce5d

Browse files
committed
docs: 更新文档
1 parent 31cf2bd commit c11ce5d

File tree

11 files changed

+422
-5
lines changed

11 files changed

+422
-5
lines changed

assets/Java/JavaCore/Java_IO.xmind

27.9 KB
Binary file not shown.

assets/分布式/分布式.xmind

-1.12 KB
Binary file not shown.
-25.3 KB
Binary file not shown.

assets/分布式/分布式调度/流量控制.drawio

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.
-3.4 KB
Binary file not shown.
-2.48 KB
Binary file not shown.

assets/知识图谱.xmind

-79.9 KB
Binary file not shown.

docs/01.Java/JavaCore/面试/Java_面试_并发(一).md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ permalink: /pages/37e2c2f3/
8282
- **协程**:用户态线程,高效但需主动让出控制权。
8383
- **管程**:同步工具,简化多线程资源共享。
8484

85-
进程和线程的差异
85+
**进程和线程的差异**
8686

8787
- 一个程序至少有一个进程,一个进程至少有一个线程。
8888
- 线程比进程划分更细,所以执行开销更小,并发性更高
@@ -92,6 +92,10 @@ permalink: /pages/37e2c2f3/
9292

9393
JVM 在单个进程中运行,JVM 中的线程共享属于该进程的堆。这就是为什么几个线程可以访问同一个对象。线程共享堆并拥有自己的堆栈空间。这是一个线程如何调用一个方法以及它的局部变量是如何保持线程安全的。但是堆不是线程安全的并且为了线程安全必须进行同步。
9494

95+
**线程和协程的差异**
96+
97+
![](https://raw.githubusercontent.com/dunwu/images/master/archive/2026/02/c435cd36568b570f8ef97a632f01200b.jpg)
98+
9599
### 【中等】Java 线程和操作系统的线程有什么区别?⭐
96100

97101
- **早期**:JVM 使用**用户线程(绿色线程)**,多个 Java 线程映射到一个 OS 线程(M:1)。
@@ -542,6 +546,8 @@ void read() {
542546
- **不要滥用**:仅适用于简单状态同步,复杂操作仍需锁或原子类。
543547
- **不适用于复合操作**:如 `check-then-act`(需 `synchronized` 或 CAS)。
544548

549+
![](https://raw.githubusercontent.com/dunwu/images/master/archive/2026/02/76b2fbb0de08297de602cec87fbc9846.jpg)
550+
545551
::: info 保证可见性
546552

547553
:::
@@ -956,6 +962,8 @@ final List<String> unsafeList = new ArrayList<>();
956962
- 使用 `CompletableFuture`
957963
- ...
958964

965+
![](https://raw.githubusercontent.com/dunwu/images/master/archive/2026/02/914774c637b6bb6d5b7de0bef5a2767b.png)
966+
959967
虽然,看似有多种多样的创建线程方式。但是,**从本质上来说,Java 就只有一种方式可以创建线程,那就是通过 `new Thread().start() ` 创建。不管是哪种方式,最终还是依赖于 `new Thread().start()`**
960968

961969
> 👉 扩展阅读:[大家都说 Java 有三种创建线程的方式!并发编程中的惊天骗局!](https://mp.weixin.qq.com/s/NspUsyhEmKnJ-4OprRFp9g)
@@ -1087,6 +1095,8 @@ Java 的线程是不允许启动两次的,**第二次调用 `Thread.start()`
10871095
| **`Thread.join()`** | `Thread` | **等待目标线程执行完毕**(阻塞当前线程) | ❌ 不释放锁 | 线程顺序执行,如主线程等待子线程结束 |
10881096
| **`Object.wait()`** | `Object` | **释放锁并进入等待,直到 `notify()`/`notifyAll()` 唤醒** | ✔️ 释放锁 | 线程间通信(需在 `synchronized` 块中使用) |
10891097

1098+
![](https://raw.githubusercontent.com/dunwu/images/master/archive/2026/02/7e80b09c6e296cceb33aacdc5b432f92.jpg)
1099+
10901100
**锁的释放**
10911101

10921102
- `wait()` 会释放锁,其他方法不会。
@@ -1124,6 +1134,8 @@ Java 的线程是不允许启动两次的,**第二次调用 `Thread.start()`
11241134
- **`Thread` 类职责分离**`Thread` 类管理线程生命周期(如 `sleep()``join()`),而 `wait()`/`notify()`**线程间协作机制**,属于锁(对象)的行为。
11251135
- **设计一致性与历史原因**:遵循 **Monitor 模式**(操作系统同步原语),保持 `Thread` 简洁,避免功能混淆(如 `wait()``sleep()` 的误用)。
11261136

1137+
![](https://raw.githubusercontent.com/dunwu/images/master/archive/2026/02/7f363a4db65944fc23f779997734df6f.jpg)
1138+
11271139
### 【中等】为什么 `Object.wait()``Object.notify()``Object.notifyAll()` 必须在 `synchronized` 方法/块中被调用?⭐
11281140

11291141
当一个线程需要调用对象的 `wait()` 方法的时候,这个线程必须拥有该对象的锁,接着它就会释放这个对象锁并进入等待状态直到其他线程调用这个对象上的 `notify()` 方法。同样的,当一个线程需要调用对象的 `notify()` 方法时,它会释放这个对象的锁,以便其他在等待的线程就可以得到这个对象锁。

docs/01.Java/JavaCore/面试/Java_面试_并发(三).md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ Java 提供了多种创建线程池的方法,主要通过 `java.util.concurren
5050
- **`CachedThreadPool`**: 可根据实际情况调整线程数量的线程池。线程池的线程数量不确定,但若有空闲线程可以复用,则会优先使用可复用的线程。若所有线程均在工作,又有新的任务提交,则会创建新的线程处理任务。所有线程在当前任务执行完毕后,将返回线程池进行复用。
5151
- **`ScheduledThreadPool`**:给定的延迟后运行任务或者定期执行任务的线程池。
5252

53+
![](https://raw.githubusercontent.com/dunwu/images/master/archive/2026/02/3eb5fff39bec5cd51950b9f11e4499ca.jpg)
54+
5355
**(2)直接使用 `ThreadPoolExecutor` 构造器**
5456

5557
```java
@@ -330,6 +332,8 @@ private boolean addWorker(Runnable firstTask, boolean core) {
330332

331333
**根据任务类型设置线程数指导**
332334

335+
![](https://raw.githubusercontent.com/dunwu/images/master/archive/2026/02/57c20e84d64150eae2f7a907c033a9be.png)
336+
333337
| 场景 | 推荐设置 | 关键考虑 |
334338
| :--------- | :--------------------------- | :--------------------------- |
335339
| CPU 密集型 | `核心数+1` | 避免上下文切换 |
@@ -363,6 +367,8 @@ private boolean addWorker(Runnable firstTask, boolean core) {
363367

364368
**最佳实践**
365369

370+
![](https://raw.githubusercontent.com/dunwu/images/master/archive/2026/02/d2eb46cd51e067e94f23768a087283ab.jpg)
371+
366372
- 通过 `Runtime.getRuntime().availableProcessors()` 获取核心数
367373
- 配合有界队列+合理拒绝策略
368374
- 建立线程池监控(活跃线程/队列堆积等)
@@ -571,6 +577,8 @@ executor.execute(() -> {
571577

572578
:::
573579

580+
![](https://raw.githubusercontent.com/dunwu/images/master/archive/2026/02/7140bd7ebb766e419822879f3610e11e.jpg)
581+
574582
ThreadPoolExecutor 提供了以下核心参数的动态修改方法:
575583

576584
| 参数 | 修改方法 | 注意事项 |
@@ -659,6 +667,10 @@ public class ResizableCapacityLinkedBlockingQueue<E> extends LinkedBlockingQueue
659667
> - **[Hippo4j](https://github.com/opengoofy/hippo4j)**:异步线程池框架,支持线程池动态变更&监控&报警,无需修改代码轻松引入。支持多种使用模式,轻松引入,致力于提高系统运行保障能力。
660668
> - **[Dynamic TP](https://github.com/dromara/dynamic-tp)**:轻量级动态线程池,内置监控告警功能,集成三方中间件线程池管理,基于主流配置中心(已支持 Nacos、Apollo,Zookeeper、Consul、Etcd,可通过 SPI 自定义实现)。
661669

670+
### 【中等】DelayQueueScheduledThreadPool 有什么区别?
671+
672+
![](https://raw.githubusercontent.com/dunwu/images/master/archive/2026/02/68f78c2ce2b6d26c35107b7ba59f5d96.jpg)
673+
662674
## Java 并发同步工具
663675

664676
### 【中等】CountDownLatch 的工作原理是什么?⭐⭐⭐
@@ -796,8 +808,12 @@ Semaphore 是基于 AQS 实现的限流同步工具,核心作用是**控制同
796808
- 抢许可证(`acquire()`)→ state 减 1
797809
- 还许可证(`release()`)→ state 加 1
798810
3. **两种模式**
811+
799812
- 公平:按线程等待顺序抢证,避免饥饿;
813+
800814
- 非公平(默认):直接抢证,性能更高,可能导致线程饥饿;
815+
816+
![](https://raw.githubusercontent.com/dunwu/images/master/archive/2026/02/6f8b6e4367c0b860a521f7937ad9d2e4.jpg)
801817
4. **可响应中断 / 超时**:`acquireInterruptibly()` 响应线程中断,`tryAcquire(timeout)` 支持超时放弃抢证;
802818
5. **许可证可超额归还**:`release()` 不校验线程是否持有许可证,可手动调用增加许可证(需谨慎,避免超预期限流)。
803819

@@ -883,6 +899,8 @@ Thread-4 占用资源
883899
| **典型场景** | 多任务并行后汇总 | 多阶段并行计算、回合制同步 | 限流、数据库连接池、信号量 |
884900
| **底层机制** | AQS | ReentrantLock + Condition | AQS |
885901

902+
![](https://raw.githubusercontent.com/dunwu/images/master/archive/2026/02/a2d1794274bb877273c78d461a2e6059.jpg)
903+
886904
**原理简述**
887905

888906
- `CountDownLatch` 内部维护计数器,`countDown()` 递减,`await()` 阻塞至计数器为 0 再释放所有等待线程。
@@ -1463,3 +1481,9 @@ public class ProducerConsumerDemo03 {
14631481

14641482
}
14651483
```
1484+
1485+
## Java 容器
1486+
1487+
### 【中等】Java 线程安全的集合有哪些?
1488+
1489+
![](https://raw.githubusercontent.com/dunwu/images/master/archive/2026/02/3f7e1da990267bd02ce54177e71db170.jpg)

docs/01.Java/JavaCore/面试/Java_面试_并发(二).md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,8 @@ AQS 的关键方法采用模板方法设计模式串联起来:
272272
- `synchronized` **更简单**:自动管理锁,适合基础同步需求。
273273
- **性能差异**:JDK 6 后,synchronized 经过一系列优化,两者性能接近,但 `ReentrantLock` 在高竞争场景仍略有优势。
274274

275+
![](https://raw.githubusercontent.com/dunwu/images/master/archive/2026/02/72f68a611c89a3e96031ae820b8e151b.png)
276+
275277
:::info synchronized 和 ReentrantLock 详细对比
276278

277279
:::
@@ -734,7 +736,11 @@ CAS(Compare-And-Swap)是一种无锁并发编程技术,广泛用于 Java
734736
**ABA 问题**
735737

736738
- **问题描述**:变量值从 `A``B``A`,CAS 检查时认为没有变化,但实际上已经被修改过。
739+
737740
- **影响**:可能导致数据不一致(如链表操作时节点被替换但指针仍有效)。
741+
742+
![](https://raw.githubusercontent.com/dunwu/images/master/archive/2026/02/618355492f7d56b0f59daaa20d9b406c.png)
743+
738744
- **解决方案**
739745
- 使用 **版本号/时间戳**(如 `AtomicStampedReference`)。
740746
- 使用 `boolean` 标记(如 `AtomicMarkableReference`)。
@@ -944,6 +950,8 @@ ThreadLocal 是**线程本地变量**,核心作用是为每个线程创建独
944950

945951
:::
946952

953+
![](https://raw.githubusercontent.com/dunwu/images/master/archive/2026/02/6af22e21d042986b11a54ef0ba0f4a10.jpg)
954+
947955
| 角色 | 作用(记忆点) | 核心关系 |
948956
| :------------: | :--------------------------------------: | :-----------------------------------------: |
949957
| ThreadLocal | 对外暴露的操作入口(get/set/remove) | 作为 Key,关联线程的变量副本 |
@@ -980,6 +988,8 @@ ThreadLocal 是**线程本地变量**,核心作用是为每个线程创建独
980988
| 核心矛盾 | ThreadLocalMap 的 Key 是弱引用(GC 回收),Value 是强引用(绑定线程),导致 Key 回收后 Value 成 “僵尸值”,随线程长期存活 |
981989
| 高危场景 | 线程池(线程复用)+ 未手动清理 → 僵尸值累积,内存持续泄漏 |
982990

991+
![](https://raw.githubusercontent.com/dunwu/images/master/archive/2026/02/c2f30f54363ae780b9297fc0b5939f59.jpg)
992+
983993
::: info ThreadLocal 内存泄露场景
984994

985995
:::

0 commit comments

Comments
 (0)