前言:并发编程的思考
“并发编程不是为了快,而是为了在正确的前提下,尽可能地快。”
在我学习Java的过程中,踩过一些坑:数据随机错乱、程序莫名其妙卡死、CPU飙升100%…每一个问题背后,都指向并发基础的不牢固。今天,我将梳理并发编程基础内容——从进程线程的本质,到线程的创建与控制,再到并发编程面临的核心挑战。

1. 进程与线程:操作系统层面的本质区别
1.1 核心定义与关系
| 定义 | 程序的一次执行过程,是操作系统资源分配的基本单位 | 进程中的一个执行流,是CPU调度的最小单位 |
| 内存空间 | 独立的地址空间,进程间内存隔离 | 共享所属进程的内存空间(堆、方法区) |
| 资源开销 | 创建/销毁开销大,上下文切换成本高 | 创建/销毁开销小,切换成本低 |
| 通信方式 | IPC(管道、消息队列、共享内存、Socket等) | 直接读写共享变量(需同步机制) |
| 健壮性 | 一个进程崩溃不影响其他进程 | 一个线程崩溃可能导致整个进程退出 |
关系本质:线程是进程内部的执行单元,一个进程至少包含一个线程(主线程),可以包含多个线程。线程共享进程的资源,但拥有独立的程序计数器、虚拟机栈和本地方法栈。
1.2 为什么线程需要独立的程序计数器?
这是多线程能够“交替执行”的关键
线程切换时,需要保存当前线程的执行位置,下次切换回来才能继续执行。程序计数器(PC)就是记录“当前执行到哪条字节码指令”的寄存器。如果线程不独立拥有PC,切换后无法恢复执行位置。
1.3 Java线程状态与操作系统线程状态的关系
Java线程状态(java.lang.Thread.State枚举)与操作系统线程状态存在映射关系,但并非完全一一对应。
Java线程状态转换图(基于JVM规范):
#mermaid-svg-f8dIsPKCiPAek4AL{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-f8dIsPKCiPAek4AL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-f8dIsPKCiPAek4AL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-f8dIsPKCiPAek4AL .error-icon{fill:#552222;}#mermaid-svg-f8dIsPKCiPAek4AL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-f8dIsPKCiPAek4AL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-f8dIsPKCiPAek4AL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-f8dIsPKCiPAek4AL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-f8dIsPKCiPAek4AL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-f8dIsPKCiPAek4AL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-f8dIsPKCiPAek4AL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-f8dIsPKCiPAek4AL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-f8dIsPKCiPAek4AL .marker.cross{stroke:#333333;}#mermaid-svg-f8dIsPKCiPAek4AL svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-f8dIsPKCiPAek4AL p{margin:0;}#mermaid-svg-f8dIsPKCiPAek4AL defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-f8dIsPKCiPAek4AL g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-f8dIsPKCiPAek4AL g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-f8dIsPKCiPAek4AL g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-f8dIsPKCiPAek4AL g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-f8dIsPKCiPAek4AL g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-f8dIsPKCiPAek4AL .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-f8dIsPKCiPAek4AL .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-f8dIsPKCiPAek4AL .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-f8dIsPKCiPAek4AL .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-f8dIsPKCiPAek4AL .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-f8dIsPKCiPAek4AL .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-f8dIsPKCiPAek4AL .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-f8dIsPKCiPAek4AL .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-f8dIsPKCiPAek4AL .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-f8dIsPKCiPAek4AL .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-f8dIsPKCiPAek4AL .edgeLabel .label text{fill:#333;}#mermaid-svg-f8dIsPKCiPAek4AL .label div .edgeLabel{color:#333;}#mermaid-svg-f8dIsPKCiPAek4AL .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-f8dIsPKCiPAek4AL .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-f8dIsPKCiPAek4AL .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-f8dIsPKCiPAek4AL .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-f8dIsPKCiPAek4AL .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-f8dIsPKCiPAek4AL .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-f8dIsPKCiPAek4AL .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-f8dIsPKCiPAek4AL #statediagram-barbEnd{fill:#333333;}#mermaid-svg-f8dIsPKCiPAek4AL .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-f8dIsPKCiPAek4AL .cluster-label,#mermaid-svg-f8dIsPKCiPAek4AL .nodeLabel{color:#131300;}#mermaid-svg-f8dIsPKCiPAek4AL .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-f8dIsPKCiPAek4AL .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-f8dIsPKCiPAek4AL .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-f8dIsPKCiPAek4AL .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-f8dIsPKCiPAek4AL .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-f8dIsPKCiPAek4AL .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-f8dIsPKCiPAek4AL .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-f8dIsPKCiPAek4AL .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-f8dIsPKCiPAek4AL .note-edge{stroke-dasharray:5;}#mermaid-svg-f8dIsPKCiPAek4AL .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-f8dIsPKCiPAek4AL .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-f8dIsPKCiPAek4AL .statediagram-note text{fill:black;}#mermaid-svg-f8dIsPKCiPAek4AL .statediagram-note .nodeLabel{color:black;}#mermaid-svg-f8dIsPKCiPAek4AL .statediagram .edgeLabel{color:red;}#mermaid-svg-f8dIsPKCiPAek4AL #dependencyStart,#mermaid-svg-f8dIsPKCiPAek4AL #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-f8dIsPKCiPAek4AL .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-f8dIsPKCiPAek4AL :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
new Thread()
start()
等待synchronized锁
wait()/join()/park()
sleep(time)/wait(time)/join(time)/parkNanos()
获取到锁
notify()/notifyAll()/unpark()
超时/唤醒
run()执行完毕/未捕获异常
NEW
RUNNABLE
BLOCKED
WAITING
TIMED_WAITING
TERMINATED
关键认知:
- RUNNABLE状态是Java特有的合并状态,包含了操作系统的就绪(Ready)和运行(Running)两个状态。JVM层面不区分是否正在占用CPU,因为这是操作系统调度器的工作。
- BLOCKED状态专指等待synchronized监视器锁时的阻塞。使用Lock接口(如ReentrantLock)等待锁时,线程处于WAITING状态,而非BLOCKED。
- WAITING/TIMED_WAITING是主动进入的等待状态,需要被显式唤醒才能恢复。
思考:为什么JVM不把RUNNABLE拆分为就绪和运行?
因为Java层面无法控制CPU调度,一个线程在Java层面是RUNNABLE,在操作系统层面可能在等待CPU时间片。如果拆分开,状态会频繁变化,但无法被Java程序有效观测,反而增加复杂性。
2. 并发编程的优势与挑战
2.1 并发编程的三大优势
2.2 并发编程的四大挑战
2.2.1 上下文切换
现象:CPU通过时间片分配算法循环执行任务,切换前保存当前任务状态,下次切换回来再加载。即CPU进行线程占用切换。这个过程就是上下文切换。
减少上下文切换的策略:
| 无锁并发编程 | 避免锁竞争导致的线程阻塞 | 数据分段、ThreadLocal |
| CAS算法 | 非阻塞原子操作,避免线程挂起 | AtomicInteger |
| 最少线程原则 | 线程数=任务数+α,避免过多空闲线程 | 合理设置线程池大小 |
| 协程 | 用户态调度,切换成本极低 | Go goroutine,Java虚拟线程 |
2.2.2 死锁
死锁四必要条件(必须同时满足):
死锁检测与预防:
// 死锁检测:使用jstack命令
// 1. jps 找到Java进程PID
// 2. jstack -l <PID> 查看线程栈,会输出Found one Java-level deadlock
// 预防策略对比
public class DeadlockPrevention {
// 策略1:按固定顺序获取锁(打破环路等待)
public void transferMoney(Account from, Account to, int amount) {
// 根据账户ID排序,确保锁获取顺序一致
Account first = from.hashCode() < to.hashCode() ? from : to;
Account second = from.hashCode() < to.hashCode() ? to : from;
synchronized(first) {
synchronized(second) {
// 转账逻辑
}
}
}
// 策略2:使用定时锁(打破不可剥夺)
public boolean tryTransfer(Account from, Account to, int amount) {
while(true) {
if (from.lock.tryLock(50, TimeUnit.MILLISECONDS)) {
try {
if (to.lock.tryLock(50, TimeUnit.MILLISECONDS)) {
try {
// 转账成功
return true;
} finally {
to.lock.unlock();
}
}
} finally {
from.lock.unlock();
}
}
// 获取锁失败,重试或放弃
}
}
}
2.2.3 线程安全
定义:当多个线程访问某个类时,无论运行时环境如何调度,都不需要额外的同步措施,这个类始终表现出正确的行为,则称该类是线程安全的。
线程安全问题的根源:
- 原子性问题:复合操作(如count++)在多线程下被打断
- 可见性问题:一个线程修改了变量,其他线程不可见
- 有序性问题:指令重排序导致意外的执行顺序
2.2.4 资源限制
硬件资源限制:带宽、硬盘读写速度、CPU处理速度
软件资源限制:数据库连接数、Socket连接数
应对策略:
- 集群化:多机并行处理
- 资源池化:连接池复用连接
- 并发度调优:根据资源瓶颈调整线程数
3. 线程创建方式:四种实现及其本质差异
3.1 四种创建方式对比
| 继承Thread | 简单 | 否 | 否 | 简单任务,不要求继承其他类 |
| 实现Runnable | 简单 | 否 | 否 | 资源共享场景,避免单继承限制 |
| Callable+Future | 中等 | 能 | 能 | 需要获取线程执行结果的场景 |
| 线程池 | 较复杂 | 能 | 能 | 频繁创建/销毁线程的场景 |
3.2 实现Runnable与继承Thread的本质区别
// 方式1:继承Thread
class MyThread extends Thread {
@Override
public void run() {
System.out.println("Thread running");
}
}
new MyThread().start();
// 方式2:实现Runnable
class MyTask implements Runnable {
@Override
public void run() {
System.out.println("Task running");
}
}
new Thread(new MyTask()).start();
深度思考:Runnable方式的优势不仅仅是“避免单继承限制”,更重要的是解耦——将“任务”与“执行者”分离。
- 任务:业务逻辑(Runnable)
- 执行者:线程(Thread)
这种分离使得:
3.3 Callable与Future:带返回值的线程
public class CallableDemo {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(1);
Callable<Integer> task = () -> {
Thread.sleep(1000); // 模拟耗时计算
return 42;
};
Future<Integer> future = executor.submit(task);
try {
// get()会阻塞当前线程,直到任务完成
Integer result = future.get(2, TimeUnit.SECONDS);
System.out.println("计算结果: " + result);
} catch (TimeoutException e) {
System.out.println("计算超时");
future.cancel(true); // 尝试中断任务
} catch (Exception e) {
e.printStackTrace();
}
executor.shutdown();
}
}
Future接口的核心方法:
- get():阻塞获取结果
- get(timeout, unit):限时等待
- cancel(boolean mayInterruptIfRunning):取消任务
- isDone():任务是否完成
- isCancelled():任务是否被取消
FutureTask的本质:它既是Runnable(可以被线程执行),又是Future(可以获取结果),实现了任务执行与结果获取的统一。
4. Thread核心方法:控制线程的行为
4.1 start() vs run()
Thread t = new Thread(() -> System.out.println("执行线程: " + Thread.currentThread().getName()));
t.run(); // 输出:执行线程: main
t.start(); // 输出:执行线程: Thread-0
本质区别:
- run():普通方法调用,在当前线程同步执行
- start():启动新线程,JVM为新线程分配资源,调用run()方法
思考:为什么start()不能多次调用?
因为线程一旦启动,就加入了线程调度,不能再重置。多次调用start()会抛出IllegalThreadStateException。
4.2 sleep():暂停而不释放锁
public class SleepDemo {
private static final Object lock = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
synchronized(lock) {
try {
System.out.println("T1持有锁,开始睡眠");
Thread.sleep(3000); // 睡眠时不释放锁
System.out.println("T1醒来");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(() -> {
System.out.println("T2尝试获取锁");
synchronized(lock) {
System.out.println("T2获取到锁");
}
});
t1.start();
t2.start(); // t2会阻塞,直到t1释放锁
}
}
核心特点:
- 使当前线程进入TIMED_WAITING状态
- 不释放任何锁(包括synchronized和Lock)
- 时间到后自动进入RUNNABLE状态,等待CPU调度
4.3 yield():谦让但不一定有用
Thread.yield(); // 暗示调度器:当前线程愿意让出CPU
思考:yield真的能让出CPU吗?
不一定。yield只是给调度器一个提示,调度器可以忽略它。即使让出CPU,当前线程仍然可能立即又被调度。
实际价值:在调试或特定算法中,可以用yield增加线程切换的概率,暴露潜在的并发问题。
4.4 join():等待线程终止
public class JoinDemo {
public static void main(String[] args) throws InterruptedException {
Thread worker = new Thread(() -> {
try {
Thread.sleep(2000);
System.out.println("worker执行完毕");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
worker.start();
worker.join(); // 主线程阻塞,等待worker线程结束
System.out.println("主线程继续执行");
}
}
实现原理:join()底层调用wait(0),等待目标线程执行完notify(实际上线程终止时会自动调用notifyAll)。
5. 线程中断机制:协作式的优雅终止
5.1 中断的本质(必须深刻理解)
核心认知:中断是协作式的,不是抢占式的。调用interrupt()并不会强制停止线程,只是设置一个中断状态标志。
public class InterruptMechanism {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
while (true) {
if (Thread.currentThread().isInterrupted()) {
System.out.println("检测到中断,优雅退出");
// 执行清理工作
break;
}
// 正常任务
System.out.println("working…");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// sleep时被中断,会清除中断标志并抛出异常
System.out.println("sleep时被中断");
// 重要:重新设置中断标志,让循环检测到
Thread.currentThread().interrupt();
}
}
});
t.start();
Thread.sleep(3000);
t.interrupt(); // 设置中断标志
}
}
5.2 三个中断方法的核心区别
| interrupt() | 目标线程 | 否(设置中断状态) | void |
| isInterrupted() | 当前线程对象 | 否 | 当前中断状态 |
| interrupted() | 当前线程 | 是 | 调用前的中断状态 |
public class InterruptMethodsDemo {
public static void main(String[] args) {
Thread.currentThread().interrupt(); // 设置主线程中断
// 第一次调用interrupted(),返回true并清除中断状态
boolean first = Thread.interrupted();
System.out.println("第一次interrupted(): " + first); // true
// 第二次调用interrupted(),中断状态已被清除
boolean second = Thread.interrupted();
System.out.println("第二次interrupted(): " + second); // false
// 再次设置中断状态
Thread.currentThread().interrupt();
// isInterrupted()只返回状态,不清除
boolean third = Thread.currentThread().isInterrupted();
System.out.println("isInterrupted(): " + third); // true
boolean fourth = Thread.currentThread().isInterrupted();
System.out.println("再次isInterrupted(): " + fourth); // true(状态没变)
}
}
为什么要有interrupted()这个会清除状态的方法?
因为中断是一种“信号机制”,当线程通过interrupted()检查到中断后,需要处理中断。处理完后,中断标志应该被清除,避免下次再次检查时重复处理。典型的模式是:
总结:并发基础思维导图
#mermaid-svg-0OFmcSJxYStwuI8n{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0OFmcSJxYStwuI8n .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0OFmcSJxYStwuI8n .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0OFmcSJxYStwuI8n .error-icon{fill:#552222;}#mermaid-svg-0OFmcSJxYStwuI8n .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0OFmcSJxYStwuI8n .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0OFmcSJxYStwuI8n .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0OFmcSJxYStwuI8n .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0OFmcSJxYStwuI8n .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0OFmcSJxYStwuI8n .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0OFmcSJxYStwuI8n .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0OFmcSJxYStwuI8n .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0OFmcSJxYStwuI8n .marker.cross{stroke:#333333;}#mermaid-svg-0OFmcSJxYStwuI8n svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0OFmcSJxYStwuI8n p{margin:0;}#mermaid-svg-0OFmcSJxYStwuI8n .edge{stroke-width:3;}#mermaid-svg-0OFmcSJxYStwuI8n .section–1 rect,#mermaid-svg-0OFmcSJxYStwuI8n .section–1 path,#mermaid-svg-0OFmcSJxYStwuI8n .section–1 circle,#mermaid-svg-0OFmcSJxYStwuI8n .section–1 polygon,#mermaid-svg-0OFmcSJxYStwuI8n .section–1 path{fill:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-0OFmcSJxYStwuI8n .section–1 text{fill:#ffffff;}#mermaid-svg-0OFmcSJxYStwuI8n .node-icon–1{font-size:40px;color:#ffffff;}#mermaid-svg-0OFmcSJxYStwuI8n .section-edge–1{stroke:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-0OFmcSJxYStwuI8n .edge-depth–1{stroke-width:17;}#mermaid-svg-0OFmcSJxYStwuI8n .section–1 line{stroke:hsl(60, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-0OFmcSJxYStwuI8n .disabled,#mermaid-svg-0OFmcSJxYStwuI8n .disabled circle,#mermaid-svg-0OFmcSJxYStwuI8n .disabled text{fill:lightgray;}#mermaid-svg-0OFmcSJxYStwuI8n .disabled text{fill:#efefef;}#mermaid-svg-0OFmcSJxYStwuI8n .section-0 rect,#mermaid-svg-0OFmcSJxYStwuI8n .section-0 path,#mermaid-svg-0OFmcSJxYStwuI8n .section-0 circle,#mermaid-svg-0OFmcSJxYStwuI8n .section-0 polygon,#mermaid-svg-0OFmcSJxYStwuI8n .section-0 path{fill:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-0OFmcSJxYStwuI8n .section-0 text{fill:black;}#mermaid-svg-0OFmcSJxYStwuI8n .node-icon-0{font-size:40px;color:black;}#mermaid-svg-0OFmcSJxYStwuI8n .section-edge-0{stroke:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-0OFmcSJxYStwuI8n .edge-depth-0{stroke-width:14;}#mermaid-svg-0OFmcSJxYStwuI8n .section-0 line{stroke:hsl(240, 100%, 83.5294117647%);stroke-width:3;}#mermaid-svg-0OFmcSJxYStwuI8n .disabled,#mermaid-svg-0OFmcSJxYStwuI8n .disabled circle,#mermaid-svg-0OFmcSJxYStwuI8n .disabled text{fill:lightgray;}#mermaid-svg-0OFmcSJxYStwuI8n .disabled text{fill:#efefef;}#mermaid-svg-0OFmcSJxYStwuI8n .section-1 rect,#mermaid-svg-0OFmcSJxYStwuI8n .section-1 path,#mermaid-svg-0OFmcSJxYStwuI8n .section-1 circle,#mermaid-svg-0OFmcSJxYStwuI8n .section-1 polygon,#mermaid-svg-0OFmcSJxYStwuI8n .section-1 path{fill:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-0OFmcSJxYStwuI8n .section-1 text{fill:black;}#mermaid-svg-0OFmcSJxYStwuI8n .node-icon-1{font-size:40px;color:black;}#mermaid-svg-0OFmcSJxYStwuI8n .section-edge-1{stroke:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-0OFmcSJxYStwuI8n .edge-depth-1{stroke-width:11;}#mermaid-svg-0OFmcSJxYStwuI8n .section-1 line{stroke:hsl(260, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-0OFmcSJxYStwuI8n .disabled,#mermaid-svg-0OFmcSJxYStwuI8n .disabled circle,#mermaid-svg-0OFmcSJxYStwuI8n .disabled text{fill:lightgray;}#mermaid-svg-0OFmcSJxYStwuI8n .disabled text{fill:#efefef;}#mermaid-svg-0OFmcSJxYStwuI8n .section-2 rect,#mermaid-svg-0OFmcSJxYStwuI8n .section-2 path,#mermaid-svg-0OFmcSJxYStwuI8n .section-2 circle,#mermaid-svg-0OFmcSJxYStwuI8n .section-2 polygon,#mermaid-svg-0OFmcSJxYStwuI8n .section-2 path{fill:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-0OFmcSJxYStwuI8n .section-2 text{fill:#ffffff;}#mermaid-svg-0OFmcSJxYStwuI8n .node-icon-2{font-size:40px;color:#ffffff;}#mermaid-svg-0OFmcSJxYStwuI8n .section-edge-2{stroke:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-0OFmcSJxYStwuI8n .edge-depth-2{stroke-width:8;}#mermaid-svg-0OFmcSJxYStwuI8n .section-2 line{stroke:hsl(90, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-0OFmcSJxYStwuI8n .disabled,#mermaid-svg-0OFmcSJxYStwuI8n .disabled circle,#mermaid-svg-0OFmcSJxYStwuI8n .disabled text{fill:lightgray;}#mermaid-svg-0OFmcSJxYStwuI8n .disabled text{fill:#efefef;}#mermaid-svg-0OFmcSJxYStwuI8n .section-3 rect,#mermaid-svg-0OFmcSJxYStwuI8n .section-3 path,#mermaid-svg-0OFmcSJxYStwuI8n .section-3 circle,#mermaid-svg-0OFmcSJxYStwuI8n .section-3 polygon,#mermaid-svg-0OFmcSJxYStwuI8n .section-3 path{fill:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-0OFmcSJxYStwuI8n .section-3 text{fill:black;}#mermaid-svg-0OFmcSJxYStwuI8n .node-icon-3{font-size:40px;color:black;}#mermaid-svg-0OFmcSJxYStwuI8n .section-edge-3{stroke:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-0OFmcSJxYStwuI8n .edge-depth-3{stroke-width:5;}#mermaid-svg-0OFmcSJxYStwuI8n .section-3 line{stroke:hsl(120, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-0OFmcSJxYStwuI8n .disabled,#mermaid-svg-0OFmcSJxYStwuI8n .disabled circle,#mermaid-svg-0OFmcSJxYStwuI8n .disabled text{fill:lightgray;}#mermaid-svg-0OFmcSJxYStwuI8n .disabled text{fill:#efefef;}#mermaid-svg-0OFmcSJxYStwuI8n .section-4 rect,#mermaid-svg-0OFmcSJxYStwuI8n .section-4 path,#mermaid-svg-0OFmcSJxYStwuI8n .section-4 circle,#mermaid-svg-0OFmcSJxYStwuI8n .section-4 polygon,#mermaid-svg-0OFmcSJxYStwuI8n .section-4 path{fill:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-0OFmcSJxYStwuI8n .section-4 text{fill:black;}#mermaid-svg-0OFmcSJxYStwuI8n .node-icon-4{font-size:40px;color:black;}#mermaid-svg-0OFmcSJxYStwuI8n .section-edge-4{stroke:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-0OFmcSJxYStwuI8n .edge-depth-4{stroke-width:2;}#mermaid-svg-0OFmcSJxYStwuI8n .section-4 line{stroke:hsl(150, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-0OFmcSJxYStwuI8n .disabled,#mermaid-svg-0OFmcSJxYStwuI8n .disabled circle,#mermaid-svg-0OFmcSJxYStwuI8n .disabled text{fill:lightgray;}#mermaid-svg-0OFmcSJxYStwuI8n .disabled text{fill:#efefef;}#mermaid-svg-0OFmcSJxYStwuI8n .section-5 rect,#mermaid-svg-0OFmcSJxYStwuI8n .section-5 path,#mermaid-svg-0OFmcSJxYStwuI8n .section-5 circle,#mermaid-svg-0OFmcSJxYStwuI8n .section-5 polygon,#mermaid-svg-0OFmcSJxYStwuI8n .section-5 path{fill:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-0OFmcSJxYStwuI8n .section-5 text{fill:black;}#mermaid-svg-0OFmcSJxYStwuI8n .node-icon-5{font-size:40px;color:black;}#mermaid-svg-0OFmcSJxYStwuI8n .section-edge-5{stroke:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-0OFmcSJxYStwuI8n .edge-depth-5{stroke-width:-1;}#mermaid-svg-0OFmcSJxYStwuI8n .section-5 line{stroke:hsl(180, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-0OFmcSJxYStwuI8n .disabled,#mermaid-svg-0OFmcSJxYStwuI8n .disabled circle,#mermaid-svg-0OFmcSJxYStwuI8n .disabled text{fill:lightgray;}#mermaid-svg-0OFmcSJxYStwuI8n .disabled text{fill:#efefef;}#mermaid-svg-0OFmcSJxYStwuI8n .section-6 rect,#mermaid-svg-0OFmcSJxYStwuI8n .section-6 path,#mermaid-svg-0OFmcSJxYStwuI8n .section-6 circle,#mermaid-svg-0OFmcSJxYStwuI8n .section-6 polygon,#mermaid-svg-0OFmcSJxYStwuI8n .section-6 path{fill:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-0OFmcSJxYStwuI8n .section-6 text{fill:black;}#mermaid-svg-0OFmcSJxYStwuI8n .node-icon-6{font-size:40px;color:black;}#mermaid-svg-0OFmcSJxYStwuI8n .section-edge-6{stroke:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-0OFmcSJxYStwuI8n .edge-depth-6{stroke-width:-4;}#mermaid-svg-0OFmcSJxYStwuI8n .section-6 line{stroke:hsl(210, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-0OFmcSJxYStwuI8n .disabled,#mermaid-svg-0OFmcSJxYStwuI8n .disabled circle,#mermaid-svg-0OFmcSJxYStwuI8n .disabled text{fill:lightgray;}#mermaid-svg-0OFmcSJxYStwuI8n .disabled text{fill:#efefef;}#mermaid-svg-0OFmcSJxYStwuI8n .section-7 rect,#mermaid-svg-0OFmcSJxYStwuI8n .section-7 path,#mermaid-svg-0OFmcSJxYStwuI8n .section-7 circle,#mermaid-svg-0OFmcSJxYStwuI8n .section-7 polygon,#mermaid-svg-0OFmcSJxYStwuI8n .section-7 path{fill:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-0OFmcSJxYStwuI8n .section-7 text{fill:black;}#mermaid-svg-0OFmcSJxYStwuI8n .node-icon-7{font-size:40px;color:black;}#mermaid-svg-0OFmcSJxYStwuI8n .section-edge-7{stroke:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-0OFmcSJxYStwuI8n .edge-depth-7{stroke-width:-7;}#mermaid-svg-0OFmcSJxYStwuI8n .section-7 line{stroke:hsl(270, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-0OFmcSJxYStwuI8n .disabled,#mermaid-svg-0OFmcSJxYStwuI8n .disabled circle,#mermaid-svg-0OFmcSJxYStwuI8n .disabled text{fill:lightgray;}#mermaid-svg-0OFmcSJxYStwuI8n .disabled text{fill:#efefef;}#mermaid-svg-0OFmcSJxYStwuI8n .section-8 rect,#mermaid-svg-0OFmcSJxYStwuI8n .section-8 path,#mermaid-svg-0OFmcSJxYStwuI8n .section-8 circle,#mermaid-svg-0OFmcSJxYStwuI8n .section-8 polygon,#mermaid-svg-0OFmcSJxYStwuI8n .section-8 path{fill:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-0OFmcSJxYStwuI8n .section-8 text{fill:black;}#mermaid-svg-0OFmcSJxYStwuI8n .node-icon-8{font-size:40px;color:black;}#mermaid-svg-0OFmcSJxYStwuI8n .section-edge-8{stroke:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-0OFmcSJxYStwuI8n .edge-depth-8{stroke-width:-10;}#mermaid-svg-0OFmcSJxYStwuI8n .section-8 line{stroke:hsl(330, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-0OFmcSJxYStwuI8n .disabled,#mermaid-svg-0OFmcSJxYStwuI8n .disabled circle,#mermaid-svg-0OFmcSJxYStwuI8n .disabled text{fill:lightgray;}#mermaid-svg-0OFmcSJxYStwuI8n .disabled text{fill:#efefef;}#mermaid-svg-0OFmcSJxYStwuI8n .section-9 rect,#mermaid-svg-0OFmcSJxYStwuI8n .section-9 path,#mermaid-svg-0OFmcSJxYStwuI8n .section-9 circle,#mermaid-svg-0OFmcSJxYStwuI8n .section-9 polygon,#mermaid-svg-0OFmcSJxYStwuI8n .section-9 path{fill:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-0OFmcSJxYStwuI8n .section-9 text{fill:black;}#mermaid-svg-0OFmcSJxYStwuI8n .node-icon-9{font-size:40px;color:black;}#mermaid-svg-0OFmcSJxYStwuI8n .section-edge-9{stroke:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-0OFmcSJxYStwuI8n .edge-depth-9{stroke-width:-13;}#mermaid-svg-0OFmcSJxYStwuI8n .section-9 line{stroke:hsl(0, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-0OFmcSJxYStwuI8n .disabled,#mermaid-svg-0OFmcSJxYStwuI8n .disabled circle,#mermaid-svg-0OFmcSJxYStwuI8n .disabled text{fill:lightgray;}#mermaid-svg-0OFmcSJxYStwuI8n .disabled text{fill:#efefef;}#mermaid-svg-0OFmcSJxYStwuI8n .section-10 rect,#mermaid-svg-0OFmcSJxYStwuI8n .section-10 path,#mermaid-svg-0OFmcSJxYStwuI8n .section-10 circle,#mermaid-svg-0OFmcSJxYStwuI8n .section-10 polygon,#mermaid-svg-0OFmcSJxYStwuI8n .section-10 path{fill:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-0OFmcSJxYStwuI8n .section-10 text{fill:black;}#mermaid-svg-0OFmcSJxYStwuI8n .node-icon-10{font-size:40px;color:black;}#mermaid-svg-0OFmcSJxYStwuI8n .section-edge-10{stroke:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-0OFmcSJxYStwuI8n .edge-depth-10{stroke-width:-16;}#mermaid-svg-0OFmcSJxYStwuI8n .section-10 line{stroke:hsl(30, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-0OFmcSJxYStwuI8n .disabled,#mermaid-svg-0OFmcSJxYStwuI8n .disabled circle,#mermaid-svg-0OFmcSJxYStwuI8n .disabled text{fill:lightgray;}#mermaid-svg-0OFmcSJxYStwuI8n .disabled text{fill:#efefef;}#mermaid-svg-0OFmcSJxYStwuI8n .section-root rect,#mermaid-svg-0OFmcSJxYStwuI8n .section-root path,#mermaid-svg-0OFmcSJxYStwuI8n .section-root circle,#mermaid-svg-0OFmcSJxYStwuI8n .section-root polygon{fill:hsl(240, 100%, 46.2745098039%);}#mermaid-svg-0OFmcSJxYStwuI8n .section-root text{fill:#ffffff;}#mermaid-svg-0OFmcSJxYStwuI8n .section-root span{color:#ffffff;}#mermaid-svg-0OFmcSJxYStwuI8n .section-2 span{color:#ffffff;}#mermaid-svg-0OFmcSJxYStwuI8n .icon-container{height:100%;display:flex;justify-content:center;align-items:center;}#mermaid-svg-0OFmcSJxYStwuI8n .edge{fill:none;}#mermaid-svg-0OFmcSJxYStwuI8n .mindmap-node-label{dy:1em;alignment-baseline:middle;text-anchor:middle;dominant-baseline:middle;text-align:center;}#mermaid-svg-0OFmcSJxYStwuI8n :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
root((并发编程基础))
进程与线程
本质区别
资源分配单位 vs 调度单位
线程状态
NEW
RUNNABLE
BLOCKED
WAITING
TIMED_WAITING
TERMINATED
并发挑战
上下文切换
时间片+状态保存恢复
死锁
四条件+预防策略
线程安全
原子性+可见性+有序性
资源限制
硬件限制+软件限制
线程创建
继承Thread
简单但单继承限制
实现Runnable
解耦任务与执行
Callable+Future
带返回值+异常
线程池
资源复用+控制并发
Thread核心方法
start()
启动线程
run()
普通方法调用
sleep()
TIMED_WAITING,不释放锁
yield()
谦让提示
join()
等待线程终止
中断机制
interrupt()
设置中断标志
isInterrupted()
查询不清除
interrupted()
查询并清除





