欢迎光临
我们一直在努力

JUC并发编程【八股篇】:并发基础

前言:并发编程的思考

“并发编程不是为了快,而是为了在正确的前提下,尽可能地快。”

在我学习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 并发编程的三大优势

  • 提升CPU利用率:当线程A等待I/O时,CPU可以执行线程B
  • 提高系统吞吐量:同时处理多个请求,单位时间内完成更多任务
  • 改善响应时间:耗时操作(如网络请求)异步执行,主线程不阻塞
  • 2.2 并发编程的四大挑战

    2.2.1 上下文切换

    现象:CPU通过时间片分配算法循环执行任务,切换前保存当前任务状态,下次切换回来再加载。即CPU进行线程占用切换。这个过程就是上下文切换。

    减少上下文切换的策略:

    策略原理示例
    无锁并发编程 避免锁竞争导致的线程阻塞 数据分段、ThreadLocal
    CAS算法 非阻塞原子操作,避免线程挂起 AtomicInteger
    最少线程原则 线程数=任务数+α,避免过多空闲线程 合理设置线程池大小
    协程 用户态调度,切换成本极低 Go goroutine,Java虚拟线程
    2.2.2 死锁

    死锁四必要条件(必须同时满足):

  • 互斥条件:资源同时只能被一个线程占有
  • 持有并等待:线程持有资源A,同时等待资源B
  • 不可剥夺:资源只能由持有线程主动释放
  • 环路等待:T1等待T2的资源,T2等待T1的资源
  • 死锁检测与预防:

    // 死锁检测:使用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)

    这种分离使得:

  • 同一个Runnable实例可以被多个线程共享执行
  • 任务可以交给不同的执行机制(线程池、定时执行等)
  • 符合“组合优于继承”的设计原则
  • 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()检查到中断后,需要处理中断。处理完后,中断标志应该被清除,避免下次再次检查时重复处理。典型的模式是:

  • 调用阻塞方法时抛出InterruptedException
  • 异常处理中设置中断标志(Thread.currentThread().interrupt())
  • 让上层代码能检测到中断

  • 总结:并发基础思维导图

    #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()

    查询并清除


    在这里插入图片描述

    赞(0)
    未经允许不得转载:171主机测评 » JUC并发编程【八股篇】:并发基础
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址