JAVA面试-并发篇 09-LockSupport 和 waitnotify 的区别

LockSupport 与 wait/notify 核心区别详解

一、文章概述

wait/notify是Object类的原生线程通信方法,依赖synchronized同步锁;LockSupport是JUC提供的线程阻塞唤醒工具,是AQS的核心底层组件。本文通过对比表、流程图和完整可运行代码,清晰讲解两者的使用差异与核心特性。

二、核心区别对比

对比维度 wait/notify LockSupport
使用限制 必须在同步块中,否则抛异常 无锁限制,任意位置调用
执行顺序 必须先等待后唤醒 支持先唤醒后等待
唤醒精度 随机唤醒,无法指定线程 精准唤醒目标线程
锁资源 调用wait会自动释放锁 无锁,无需释放资源

三、执行流程

wait/notify 执行流程

#mermaid-svg-D3WhhelqCzWqQmeS{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-D3WhhelqCzWqQmeS .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-D3WhhelqCzWqQmeS .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-D3WhhelqCzWqQmeS .error-icon{fill:#552222;}#mermaid-svg-D3WhhelqCzWqQmeS .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-D3WhhelqCzWqQmeS .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-D3WhhelqCzWqQmeS .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-D3WhhelqCzWqQmeS .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-D3WhhelqCzWqQmeS .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-D3WhhelqCzWqQmeS .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-D3WhhelqCzWqQmeS .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-D3WhhelqCzWqQmeS .marker{fill:#333333;stroke:#333333;}#mermaid-svg-D3WhhelqCzWqQmeS .marker.cross{stroke:#333333;}#mermaid-svg-D3WhhelqCzWqQmeS svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-D3WhhelqCzWqQmeS p{margin:0;}#mermaid-svg-D3WhhelqCzWqQmeS .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-D3WhhelqCzWqQmeS .cluster-label text{fill:#333;}#mermaid-svg-D3WhhelqCzWqQmeS .cluster-label span{color:#333;}#mermaid-svg-D3WhhelqCzWqQmeS .cluster-label span p{background-color:transparent;}#mermaid-svg-D3WhhelqCzWqQmeS .label text,#mermaid-svg-D3WhhelqCzWqQmeS span{fill:#333;color:#333;}#mermaid-svg-D3WhhelqCzWqQmeS .node rect,#mermaid-svg-D3WhhelqCzWqQmeS .node circle,#mermaid-svg-D3WhhelqCzWqQmeS .node ellipse,#mermaid-svg-D3WhhelqCzWqQmeS .node polygon,#mermaid-svg-D3WhhelqCzWqQmeS .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-D3WhhelqCzWqQmeS .rough-node .label text,#mermaid-svg-D3WhhelqCzWqQmeS .node .label text,#mermaid-svg-D3WhhelqCzWqQmeS .image-shape .label,#mermaid-svg-D3WhhelqCzWqQmeS .icon-shape .label{text-anchor:middle;}#mermaid-svg-D3WhhelqCzWqQmeS .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-D3WhhelqCzWqQmeS .rough-node .label,#mermaid-svg-D3WhhelqCzWqQmeS .node .label,#mermaid-svg-D3WhhelqCzWqQmeS .image-shape .label,#mermaid-svg-D3WhhelqCzWqQmeS .icon-shape .label{text-align:center;}#mermaid-svg-D3WhhelqCzWqQmeS .node.clickable{cursor:pointer;}#mermaid-svg-D3WhhelqCzWqQmeS .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-D3WhhelqCzWqQmeS .arrowheadPath{fill:#333333;}#mermaid-svg-D3WhhelqCzWqQmeS .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-D3WhhelqCzWqQmeS .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-D3WhhelqCzWqQmeS .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-D3WhhelqCzWqQmeS .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-D3WhhelqCzWqQmeS .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-D3WhhelqCzWqQmeS .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-D3WhhelqCzWqQmeS .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-D3WhhelqCzWqQmeS .cluster text{fill:#333;}#mermaid-svg-D3WhhelqCzWqQmeS .cluster span{color:#333;}#mermaid-svg-D3WhhelqCzWqQmeS div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-D3WhhelqCzWqQmeS .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-D3WhhelqCzWqQmeS rect.text{fill:none;stroke-width:0;}#mermaid-svg-D3WhhelqCzWqQmeS .icon-shape,#mermaid-svg-D3WhhelqCzWqQmeS .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-D3WhhelqCzWqQmeS .icon-shape p,#mermaid-svg-D3WhhelqCzWqQmeS .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-D3WhhelqCzWqQmeS .icon-shape .label rect,#mermaid-svg-D3WhhelqCzWqQmeS .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-D3WhhelqCzWqQmeS .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-D3WhhelqCzWqQmeS .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-D3WhhelqCzWqQmeS :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 获取synchronized锁
wait阻塞并释放锁
notify唤醒线程
重新竞争锁执行

LockSupport 执行流程

#mermaid-svg-V9nUbgZ0WJCRkaAI{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-V9nUbgZ0WJCRkaAI .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-V9nUbgZ0WJCRkaAI .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-V9nUbgZ0WJCRkaAI .error-icon{fill:#552222;}#mermaid-svg-V9nUbgZ0WJCRkaAI .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-V9nUbgZ0WJCRkaAI .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-V9nUbgZ0WJCRkaAI .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-V9nUbgZ0WJCRkaAI .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-V9nUbgZ0WJCRkaAI .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-V9nUbgZ0WJCRkaAI .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-V9nUbgZ0WJCRkaAI .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-V9nUbgZ0WJCRkaAI .marker{fill:#333333;stroke:#333333;}#mermaid-svg-V9nUbgZ0WJCRkaAI .marker.cross{stroke:#333333;}#mermaid-svg-V9nUbgZ0WJCRkaAI svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-V9nUbgZ0WJCRkaAI p{margin:0;}#mermaid-svg-V9nUbgZ0WJCRkaAI .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-V9nUbgZ0WJCRkaAI .cluster-label text{fill:#333;}#mermaid-svg-V9nUbgZ0WJCRkaAI .cluster-label span{color:#333;}#mermaid-svg-V9nUbgZ0WJCRkaAI .cluster-label span p{background-color:transparent;}#mermaid-svg-V9nUbgZ0WJCRkaAI .label text,#mermaid-svg-V9nUbgZ0WJCRkaAI span{fill:#333;color:#333;}#mermaid-svg-V9nUbgZ0WJCRkaAI .node rect,#mermaid-svg-V9nUbgZ0WJCRkaAI .node circle,#mermaid-svg-V9nUbgZ0WJCRkaAI .node ellipse,#mermaid-svg-V9nUbgZ0WJCRkaAI .node polygon,#mermaid-svg-V9nUbgZ0WJCRkaAI .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-V9nUbgZ0WJCRkaAI .rough-node .label text,#mermaid-svg-V9nUbgZ0WJCRkaAI .node .label text,#mermaid-svg-V9nUbgZ0WJCRkaAI .image-shape .label,#mermaid-svg-V9nUbgZ0WJCRkaAI .icon-shape .label{text-anchor:middle;}#mermaid-svg-V9nUbgZ0WJCRkaAI .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-V9nUbgZ0WJCRkaAI .rough-node .label,#mermaid-svg-V9nUbgZ0WJCRkaAI .node .label,#mermaid-svg-V9nUbgZ0WJCRkaAI .image-shape .label,#mermaid-svg-V9nUbgZ0WJCRkaAI .icon-shape .label{text-align:center;}#mermaid-svg-V9nUbgZ0WJCRkaAI .node.clickable{cursor:pointer;}#mermaid-svg-V9nUbgZ0WJCRkaAI .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-V9nUbgZ0WJCRkaAI .arrowheadPath{fill:#333333;}#mermaid-svg-V9nUbgZ0WJCRkaAI .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-V9nUbgZ0WJCRkaAI .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-V9nUbgZ0WJCRkaAI .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-V9nUbgZ0WJCRkaAI .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-V9nUbgZ0WJCRkaAI .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-V9nUbgZ0WJCRkaAI .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-V9nUbgZ0WJCRkaAI .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-V9nUbgZ0WJCRkaAI .cluster text{fill:#333;}#mermaid-svg-V9nUbgZ0WJCRkaAI .cluster span{color:#333;}#mermaid-svg-V9nUbgZ0WJCRkaAI div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-V9nUbgZ0WJCRkaAI .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-V9nUbgZ0WJCRkaAI rect.text{fill:none;stroke-width:0;}#mermaid-svg-V9nUbgZ0WJCRkaAI .icon-shape,#mermaid-svg-V9nUbgZ0WJCRkaAI .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-V9nUbgZ0WJCRkaAI .icon-shape p,#mermaid-svg-V9nUbgZ0WJCRkaAI .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-V9nUbgZ0WJCRkaAI .icon-shape .label rect,#mermaid-svg-V9nUbgZ0WJCRkaAI .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-V9nUbgZ0WJCRkaAI .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-V9nUbgZ0WJCRkaAI .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-V9nUbgZ0WJCRkaAI :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 调用park阻塞线程
unpark精准唤醒
线程恢复执行

四、完整代码示例

1. wait/notify 实现线程通信

java 复制代码
public class WaitNotifyDemo {
    private static final Object lock = new Object();
    public static void main(String[] args) {
        new Thread(() -> {
            synchronized (lock) {
                try { lock.wait(); } // 阻塞并释放锁
                catch (InterruptedException e) {}
                System.out.println("线程被唤醒");
            }
        }).start();
        new Thread(() -> {
            synchronized (lock) { lock.notify(); } // 必须加锁唤醒
        }).start();
    }
}

2. LockSupport 实现线程通信

java 复制代码
import java.util.concurrent.locks.LockSupport;
public class LockSupportDemo {
    public static void main(String[] args) {
        Thread t = new Thread(() -> {
            LockSupport.park(); // 无锁阻塞
            System.out.println("线程被精准唤醒");
        });
        t.start();
        LockSupport.unpark(t); // 精准唤醒指定线程,无需加锁
    }
}

总结

wait/notify强依赖同步锁,使用繁琐且唤醒不精准,仅适用于基础同步场景;LockSupport无使用限制、支持预唤醒、精准操作线程,规避了传统API的缺陷,是Java高并发框架的首选线程协作工具。

相关推荐
个 人 练 习 生1 分钟前
C++ string 类模拟实现:从底层理解字符串(上)
开发语言·c++·经验分享·学习·程序人生
2601_9669496511 分钟前
多市场量化策略的数据接口应该如何设计:从数据层架构到策略接入
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
坤坤子吖13 分钟前
C++智能指针:RAII、shared_ptr与内存泄漏
开发语言·c++·笔记·学习
奋斗的阿狸_198623 分钟前
ESP32-S3 + ES7210 四通道麦克风录音上传方案
c语言·开发语言·fpga开发
沐言人生35 分钟前
又一个神级考公脑库-22,375篇真题终于按考点整理了
后端·面试
夜之眷属38 分钟前
Core dump 崩溃排查:JVM 宕机后,那份 core 文件怎么用 gdb 还原现场
java·运维·服务器·jvm
weixin1997010801638 分钟前
《1688图片空间API踩坑:img.upload 与 album.* 的防盗链与CDN缓存问题》(附Python源码)
开发语言·python·缓存
波加曼大王40 分钟前
# vLLM不要迷信PagedAttention神话,聊聊线上藏着的内部碎片陷阱
java·架构
SL_staff1 小时前
目标健康度自检清单:开发者视角下的目标-计划-任务链路断点诊断
java·开源·github
for_ever_love__1 小时前
MySQL 高频面试题 30 问:索引、事务、锁、日志、主从与分库分表(MySQL 8.0 版)
java·数据库·spring boot·mysql·spring cloud·面试·总结