CountDownLatch从入门到源码:Java并发等待机制详解
Java 并发编程里头有一个工具名字取得特别形象CountDownLatch中文一般翻译成“倒计时门闩”。你可以直接把它理解成一扇门一开始门闩插得死死的所有想进门的线程都被挡在外面谁也过不去等倒计时归零的那一瞬间门闩自动抽开早就聚在门口的一堆线程哗啦一下全被放行。这个东西在业务代码里不一定会天天用但在高并发框架和面试题里出场率极高尤其适合处理“多个线程干活等齐了再继续”这类需求。这篇文章准备把它的定位、用法、底层原理和常见坑一次讲透适合刚接触并发编程的新人也适合面试前临时抱佛脚的 Java 工程师。1. 一把“倒计时门闩”到底解决了什么问题1.1 并发协作里最麻烦的“等”写一个下单接口后端要同时拉取用户信息、商品信息、库存状态、营销活动四份数据互相独立各自耗时还不一样。很多新手的第一版代码是这样写的先查用户再查商品再查库存最后查营销四个远程调用串行执行假设每个平均 200ms整体耗时就是 800ms。如果让这四个调用并发跑主线程等四份结果都齐了再汇总返回理想情况下整体耗时只等于最慢的那个接口大概是 200ms 出头性能差距肉眼可见。但问题来了并行跑起来之后主线程怎么知道四个子任务都结束了这个“等”字听起来简单实际上是并发编程里最容易出错的地方。最朴素的做法是 Thread.join()在子线程上调用 join()让主线程等待子线程终止。可 join() 有一个硬伤——它只能等“线程结束”。如果你的任务是丢进线程池执行的任务跑完线程并不会退出而是回到线程池继续待命join() 根本等不到你想要的信号。更别提 join() 没有超时机制也没有任何方式告诉你“还剩几个任务没完成”。所以需要一种更灵活的等待机制不是等待某个线程死亡而是等待某个“次数”归零。CountDownLatch 就是专门干这件事的。它和你约定的不是“人没了”而是“事办完了”。1.2 门闩动作拆解计数、放行与一次性设计CountDownLatch 在构造的时候接收一个正整数 count这个 count 就是倒计数的总数。整个工具只有两类动作。countDown() 负责把计数减一谁调用谁执行不关心是哪个线程调的更不关心调用的顺序。await() 负责把当前线程挂起直到计数归零也可以给它传一个超时时间等太久就直接放弃避免永久卡死。打个比方系统上线工单需要三个审批人全部点“同意”才能放行。只要还有一个人没点工单就卡在流程里三个人都点了流程立刻往下走。三个审批人之间不需要认识谁先点谁后点无所谓关键是那个“三票通过”的总开关。CountDownLatch 就是那把总开关countDown() 就是点“同意”await() 就是等待工单放行的流程节点。这里面有一个很容易忽略的设计门闩是一次性的。计数归零之后这个 CountDownLatch 就永久处于“开门”状态后面再有人调用 await() 会直接放行你不能再往里面塞计数、重新锁门。想要“重复使用的门”是另一回事得找 CyclicBarrier这个后面会详细对比。一次性这个特性注定了 CountDownLatch 适合“只等一次”的场景比如启动一批任务后等它们全部完成而不要试图让它承担多轮任务同步的职责。1.3 和 join()、CyclicBarrier 的定位对比面试里最经典的问题就是“CountDownLatch 和 CyclicBarrier 有什么区别”很多人的回答停留在“一个递减一个递增”这种表面层面。我习惯用下面这张表给自己理思路也推荐你们保存下来对比维度CountDownLatchThread.join()CyclicBarrier等待的对象计数器归零相当于一个“事件”线程终止参与线程互相等待到齐后一起放行可重用性一次性计数归零后不可 reset一次性线程死了不可复生可重置循环使用是否支持超时await 支持超时不支持超时await 支持超时是否支持中断支持中断支持中断支持中断具体场景一组任务完成后继续单个线程结束后继续多线程回合式同步比如分批处理CountDownLatch 关注的是“事件发生的次数”比如要等 4 个远程调用都结束计数设成 4。CyclicBarrier 关注的是“参与者的数量”比如 4 个线程约好在屏障点碰头谁先到谁先等直到 4 个都到了才一起走。一个是广播式的“信号灯”一个是汇合式的“集合点”语义完全不一样用混了代码就会出现诡异的时序问题。2. 三个实战场景从入门到进阶2.1 场景一多服务并行聚合这是最高频的用法回到下单接口的例子用 CountDownLatch 实现多服务并行聚合。这里我给出一个可以复制的骨架代码核心思路是先在线程池里把所有任务都提交出去让它们并行执行然后主线程 await() 统一等待全部完成后汇总数据。ExecutorService pool Executors.newFixedThreadPool(4); CountDownLatch latch new CountDownLatch(4); MapString, Object result new ConcurrentHashMap(); try { pool.execute(() - { try { result.put(user, userClient.getUser()); } catch (Exception e) { log.error(查询用户失败, e); } finally { latch.countDown(); } }); pool.execute(() - { try { result.put(goods, goodsClient.getGoods()); } catch (Exception e) { log.error(查询商品失败, e); } finally { latch.countDown(); } }); pool.execute(() - { try { result.put(stock, stockClient.getStock()); } catch (Exception e) { log.error(查询库存失败, e); } finally { latch.countDown(); } }); pool.execute(() - { try { result.put(promotion, promotionClient.getPromotion()); } catch (Exception e) { log.error(查询营销失败, e); } finally { latch.countDown(); } }); boolean finished latch.await(5, TimeUnit.SECONDS); if (!finished) { log.warn(还有 {} 个服务未返回先返回部分数据, latch.getCount()); } } finally { pool.shutdown(); }这段代码里有几个细节必须解释清楚。第一为什么结果集合用 ConcurrentHashMap 而不是 HashMap四个子线程会同时往 Map 里写数据普通 HashMap 在高并发 put 的时候会丢数据JDK 7 年代还出过扩容死循环的问题用 ConcurrentHashMap 是最稳妥的选择。第二为什么 countDown() 要放在 finally 里如果其中一个远程调用抛了异常而你没有执行 countDown()计数就少了一次主线程的 await() 会一直等下去接口直接挂死。把 countDown() 放在 finally 里意味着业务回调正常结束、异常结束都会执行计数一定减一这是 CountDownLatch 使用中最重要的一条铁律。还有一个很多人没想明白的点为什么不直接用 FutureFuture.get() 确实能拿到子线程的计算结果但它是阻塞方法四个 get() 如果按顺序调用第一个还没返回之前后面的结果根本拿不到。虽然线程池里四个任务已经在并行跑了get() 的逐个阻塞还是会让整体耗时长于“等齐再汇总”的理想值。CountDownLatch 的价值在于把“提交任务”和“等待完成”彻底拆开先一股脑提交再统一等待。2.2 场景二双 latch 发令枪压测并发的利器第二个场景是我在实际压测中用过很多次的模拟 N 个用户同时抢购、同时发起请求。最粗糙的做法是 for 循环里 new Thread(...).start()每个线程 run() 里直接写业务逻辑。问题是线程创建本身有开销先创建的线程可能已经跑完业务了后创建的线程才刚启动结果你压的根本不是“同时到达”而是“先后到达”测试出的并发效果失真严重。用两个 CountDownLatch 就能把“同时开始”这件事做得非常精准业内管这个叫双 latch 发令枪模式int users 50; CountDownLatch ready new CountDownLatch(users); CountDownLatch start new CountDownLatch(1); for (int i 0; i users; i) { new Thread(() - { ready.countDown(); // 报告我就位了 try { start.await(); // 等待发令枪 // 这里写真正的抢购逻辑 } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }).start(); } ready.await(); // 主线程等待全部线程就位 long begin System.nanoTime(); start.countDown(); // 扣动扳机放行这里 ready 和 start 是两个不同作用的门闩。ready 是让主线程知道“50 个线程都创建好、都执行到等待位置了”start 是让所有子线程同时开跑。第一个门闩解决“线程没准备好”的问题第二个门闩解决“启动不同步”的问题。主线程在 ready.await() 返回后立刻调用 start.countDown()因为 start 的计数是 1一次就归零所有等待 start 的线程几乎在同一时刻苏醒。用 System.nanoTime() 记录开始时间误差能控制到微秒级比在代码里 sleep(1000) 硬等线程启动靠谱得多。这种双 latch 模式在自研压测工具、JUnit 并发测试、多线程基准测试里都很常见面试如果被问到“你怎么模拟高并发”这是一个很加分的答案。2.3 场景三服务启动前置条件检查再讲一个生产环境里用得上的场景服务启动时要等数据库连接池初始化、Redis 连接打通、配置中心拉取完成这三个前置条件都满足后才能对外提供服务。有些人喜欢在启动方法里硬编码 sleep(5000)赌它 5 秒内一定能连上这种方案太脆弱了网络抖动一下 5 秒不够机器空闲时 5 秒又白白浪费。用 CountDownLatch 可以做更优雅的启动门闩。后台起几个初始化线程每个线程负责一个资源初始化完成后调用 latch.countDown()主启动流程调用 latch.await(30, TimeUnit.SECONDS)等三个资源都就绪。如果 30 秒还没齐latch.getCount() 会告诉你还剩几个没就绪方便打印日志定位问题然后再决定是重试还是标记启动失败。这个场景也呼应了前面说的一次性特性。服务从启动到对外提供服务只需要“等一次”资源就绪之后就再也不会遇到这道门了。即使服务每天发布多次每次启动 new 一个 CountDownLatch 就行旧的已经被 GC 回收没有任何历史包袱。3. 源码级原理state、CAS 与 CLH 等待队列3.1 为什么 CountDownLatch 背靠 AQS 的共享锁从面试角度讲能说出来“CountDownLatch 的底层是 AQS”这只是及格还得把逻辑链路讲清楚。AQS 是 AbstractQueuedSynchronizer 的缩写Java 并发包的基石它维护了一个 volatile 修饰的 int state 变量和一套 CLH 线程等待队列。ReentrantLock、Semaphore、CountDownLatch 这些工具本质都是在这套骨架上做定制。CountDownLatch 内部定义了一个继承 AQS 的内部类 Sync它把 AQS 的 state 直接当作自己的计数器。构造方法 new CountDownLatch(4) 传入 4底层就是 setState(4)把 state 初始化成 4。之后每一次 countDown() 都是对 state 做减一操作每一次 await() 都是在等 state 变成 0。这里要理解一个关键认知CountDownLatch 其实是一把“共享锁”。共享锁的特点是可以被多个线程同时持有而 CountDownLatch 正好符合这个特性——state 大于 0 的时候任何线程来“抢锁”都抢不到老老实实去排队state 等于 0 的时候所有正在等待的线程都能同时“抢到锁”全部放行。这种“要么全放、要么全不放”的语义和共享锁的模式天然吻合所以说它基于 AQS 共享模式实现不是设计者的偶然选择而是逻辑推演下的必然结果。3.2 countDown() 和 await() 内部到底走了什么流程CountDownLatch 加锁和释放锁的模板流程由 AQS 提供但关键的策略方法由 Sync 自己实现。我直接贴 JDK 8 里最具代表性的源码片段你们感受一下这个设计的精妙protected int tryAcquireShared(int acquires) { return (getState() 0) ? 1 : -1; } protected boolean tryReleaseShared(int releases) { for (;;) { int c getState(); if (c 0) return false; int nextc c - 1; if (compareAndSetState(c, nextc)) return nextc 0; } }先看 tryAcquireShared它只判断 state 是否等于 0。等于 0 返回正数表示“锁拿到了放行”不等于 0 返回负数表示“锁还没拿到去排队”。所以 await() 的本质听起来很直接——调用 sync.acquireSharedInterruptibly(1)如果 state 是 0 就直接通过否则当前线程会被包装成一个共享节点挂到 CLH 队列尾部通过 LockSupport.park() 进入阻塞状态等待被唤醒。再看 tryReleaseShared这是一个 CAS 死循环。每次进来先读当前 state如果已经是 0 就返回 false因为计数不能再减了减成负数没有意义。如果 state 不是 0就计算出 nextc c - 1然后用 CAS 尝试把 state 从 c 改成 nextc。CAS 失败说明有别的线程正在同时修改 state就继续自旋重试直到成功为止。当 CAS 成功且 nextc 等于 0表示这次减一恰好把计数减到 0返回 true。返回 true 之后AQS 的 releaseShared 会调用 doReleaseShared唤醒队列中处于等待状态的后继节点。因为这是共享模式唤醒之后还会一级一级往后传播把排队等待的所有线程全部唤醒。这也是为什么最后一次 countDown() 调用会让所有等待线程“几乎同时”醒过来而不是逐个蹑手蹑脚地醒来。3.3 内存可见性被大多数人忽略的 happens-before讲完源码我还想补充一个面试里很多人答不上来的点CountDownLatch 可以建立线程间的内存可见性保证。AQS 的 state 是 volatile 的Java 内存模型里的 volatile 读写天然满足 happens-before 规则。具体到 CountDownLatch线程 A 在 countDown() 之前对共享数据的所有写入在线程 B 从 await() 返回之后都是可见的。再举一个具体的例子用户服务线程把订单信息写入 ConcurrentHashMap写完之后调用 latch.countDown()主线程 await() 返回后从这个 Map 里读取订单信息一定读得到完整内容。这不是碰巧“读到了”而是 JMM 规范的硬性保证。很多并发 bug 表现为数据丢失、读到的数据还是旧值往往是团队里有人绕过了同步工具自己用裸变量在多个线程间传数据。用 CountDownLatch 做线程间的“汇合点”既能控制执行时序又能保证数据可见性一举两得。4. 踩坑记录与高频面试题4.1 坑一countDown() 没执行 主线程永久阻塞这是我职业生涯里亲眼见过的事故。当时一个多线程聚合查询接口四个线上服务并发调用其中一个服务偶发超时抛了 RuntimeException子线程直接终结但 finally 里没有 countDown()计数永远少一次主线程的 await() 又没有设置超时整个接口就那样挂住了。后来排查半天才发现不是服务没返回而是 latch 的计数没归零。从那之后我给自己定了一条规矩任何 CountDownLatch 的使用代码countDown() 必须放在 finally 块里任何 await() 必须带超时参数。await(5, TimeUnit.SECONDS) 返回 false 的时候用 latch.getCount() 查看剩余计数打印 WARN 日志再按业务做降级兜底而不是让主线程傻傻等一辈子。这条经验放到生产环境里就是“接口偶发超时”和“接口永久卡死”的区别。4.2 坑二计数与任务数量不匹配门闩提前或延后放行CountDownLatch 的构造函数参数叫 count它必须和实际要等待的任务数量严格一致。实际代码里经常出现两种错误。一种是少写任务你构造了一个计数为 5 的 latch但只提交了 4 个任务结果计数永远到不了 0主线程等到超时触发才算完。另一种是任务数量超过计数一个本来计数为 4 的 latch代码里某个任务执行了两次 countDown()计数提前归零门闩提前打开还有任务没跑完就把主流程放过去了最后拿到的聚合数据缺胳膊少腿。我的建议很朴素不要手写常量。如果任务集合是 List就 new CountDownLatch(tasks.size())如果任务数量来自配置就先用日志把配置值打出来肉眼确认一遍再使用。计数不一致的 bug 往往很难通过单测发现因为单测里任务少、速度快、放行时机的影响不明显一定要在压测场景下专门验证。4.3 坑三把 CountDownLatch 和 CyclicBarrier 混用的语义混乱面试高频题“区别”如果只在嘴上背代码里很容易写出四不像。比如有人为了让 CountDownLatch 可以重用在循环外面 new 了一次然后每一轮任务结束都重新构造一个对象——代码逻辑上没错但语义已经扭曲了。该用 CyclicBarrier 的场景偏偏用 CountDownLatch 硬凑还得手动管理对象的生命周期平白多出一堆 bug 隐患。我习惯用一个简化口诀来区分这两个工具CountDownLatch 是“一个大喇叭喊所有人出发”CyclicBarrier 是“一群人在集合点等齐了再一起走”。前者是事件驱动的广播后者是参与者驱动的汇合。如果业务是“所有前置任务完成后统一执行下一步”选 CountDownLatch如果业务是“多个线程分轮次协同每轮都要重新同步”选 CyclicBarrier。这俩的关系不是替代是互补。再补充几个面试延伸问题你们可以直接拿去当复习清单面试问题参考回答要点CountDownLatch 底层原理基于 AQS 共享锁用 state 做计数CLH 队列做等待和 CyclicBarrier 的区别一次性 vs 可重用事件等待 vs 线程汇聚关注计数 vs 关注人数计数为 0 后继续调用 countDown() 会发生什么返回 false不会抛异常计数不会变负数计数为 0 后继续调用 await() 会发生什么直接放行不会阻塞await() 超时返回 false 应该怎么处理看 getCount() 的剩余值按部分失败做兜底4.4 排查实录从 jstack 到 getCount() 的一整套定位方法如果生产环境真的遇到 CountDownLatch 卡住的问题别慌建议按下面的顺序排查。第一步用 jstack 导出线程堆栈你会看到主线程卡在 LockSupport.parkNanos 或者 AbstractQueuedSynchronizer 相关方法上等待的对象指向 CountDownLatch$Sync这就确认了卡点。第二步在代码里临时加日志打印 latch.getCount() 的剩余值如果剩余值一直大于 0说明有任务没有执行 countDown()或者数量本身就不对。第三步核对所有任务代码确认 countDown() 是否都写在 finally 里确认有没有任务重复执行了 countDown()。我的个人习惯是在构造 latch 的地方打一行日志记录预期计数在每次 countDown() 之后打一行 debug 日志记录剩余计数在 await() 返回后打一行日志记录超时状态和剩余计数。这样即使出了问题日志就能给出完整的链路不需要翻着源码猜。这套排查套路我传给过团队里好几个新人都比翻文档效率高得多。最后再说几句个人体会。我见过不少项目在启动流程里滥用 CountDownLatch动不动就 await(60, TimeUnit.SECONDS) 等一堆资源结果某个环节悄悄挂掉服务就傻傻等满一分钟才报错。我现在做方案的习惯是优先考虑 CompletableFuture 这类现代并发 API 来做异步编排能用则用确实需要精确控制“等齐再放行”的语义时再用 CountDownLatch而且一定同步评估好三件事——超时时间、失败兜底、计数器一致性。它是一把很好用的门闩但门闩用不对卡住的不是并发而是你的整个服务。

相关新闻

AWS智能客户数据平台搭建:数据管道、身份解析与避坑指南

AWS智能客户数据平台搭建:数据管道、身份解析与避坑指南

简介:这是关于智能客户数据平台(CDP)在AWS云端落地的一站式解决方案PPT,适合企业数字化转型负责人、营销技术专家和云架构师阅读。资源以单个pptx演示文稿呈现,大小约1.66MB,聚焦如何利用EC2、EMR、S3、Clo…

2026/10/7 5:10:53 阅读更多 →
DSec沙箱:Agent强化学习的环境可控性革命

DSec沙箱:Agent强化学习的环境可控性革命

1. DSec沙箱不是新玩具,是Agent训练范式的分水岭最近在几个技术社区刷到“DeepSeek摊牌DSec沙箱”这个标题,点进去发现不是营销稿,而是实打实的工程公告——他们把300万个隔离、可重置、带完整OS级行为观测能力的沙箱环境,直接接入…

2026/10/7 5:10:53 阅读更多 →
CountDownLatch实战:原理、用法与避坑指南

CountDownLatch实战:原理、用法与避坑指南

先问一个很现实的问题:一次接口请求里,你需要同时去查 5 个不同服务的数据,等它们全部返回之后才能拼装结果。你是老老实实写一个 for 循环挨个查,还是用 CountDownLatch 把 5 个查询同时丢进线程池,然后让主线程等一个…

2026/10/7 5:10:53 阅读更多 →

最新新闻

Unity节奏游戏时序校准:毫秒级音画同步实战

Unity节奏游戏时序校准:毫秒级音画同步实战

简介:这是一份面向Unity初学者的节奏游戏开发入门实践资源,聚焦C#脚本编写与音乐交互逻辑实现,帮助开发者快速掌握节拍同步、音符判定、UI反馈等核心机制。资源包含262个文件,主体为Unity工程必需的.cs脚本、.prefab预制体、.mp3音…

2026/10/7 5:38:13 阅读更多 →
企业级AI应用底座QuickBlue:微服务与JDK 21技术选型实践

企业级AI应用底座QuickBlue:微服务与JDK 21技术选型实践

1. 从一堆“重复造轮子”的痛说起如果你带过几个企业级 AI 项目,大概率经历过这样的场景:第一个项目从零搭了一套用户体系、权限模型、审计日志、模型调用网关,跑得挺好;第二个项目来了,需求类似,于是把第一…

2026/10/7 5:38:13 阅读更多 →
基于区块链的安全文件共享系统:哈希上链、权限管理与密钥信封实践

基于区块链的安全文件共享系统:哈希上链、权限管理与密钥信封实践

简介:基于区块链的安全文件共享系统毕业设计完整源码包,面向软件工程、计科、人工智能等计算机相关专业学生、教师或开发者。项目聚焦文件共享中的可信存储与权限审计,实现节点身份认证、加密通信与文件分发逻辑;源码获导师认可&a…

2026/10/7 5:38:13 阅读更多 →
模型+IK+状态机:Unity原生角色动画完整实战指南

模型+IK+状态机:Unity原生角色动画完整实战指南

之前在梳理角色动画相关方案时,很多资料都习惯引导开发者去装第三方插件,遇到“模型、IK、状态机”这三个词就把工具越堆越重。实际上,不少常见需求完全可以直接用引擎原生能力串起来,也就是标题里说的“原版插件”方案。这篇算是…

2026/10/7 5:38:13 阅读更多 →
绍兴D照驾照培训专业机构推荐 广受信赖

绍兴D照驾照培训专业机构推荐 广受信赖

绍兴D照驾照培训专业机构推荐:柯桥众华学车凭什么广受信赖 在绍兴柯桥,摩托车出行需求旺盛,D照驾照培训的报名热度逐年上升。但学员在选驾校时往往面临同样的问题:哪家收费透明?哪家通过率高?哪家能真正结合本地路况教学?本文以…

2026/10/7 5:38:13 阅读更多 →
AI驱动的接口用例智能维护:从业务变更到可执行测试指令

AI驱动的接口用例智能维护:从业务变更到可执行测试指令

1. 这不是“让AI写用例”,而是给测试团队装上业务理解的“眼睛”“接口用例越多越难维护?”——这句话我听开发和测试同事说了不下五十遍,每次都在项目上线前两周,会议室里空气都凝固了。不是大家不努力,是业务逻辑一变…

2026/10/7 5:37:13 阅读更多 →

日新闻

ROS2机械臂仿真与运动控制:从URDF建模到Gazebo实战全解析

ROS2机械臂仿真与运动控制:从URDF建模到Gazebo实战全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 1:01:58 阅读更多 →
用浏览器直接改ESP32的WiFi密码:NVS键值配置工具设计与实现

用浏览器直接改ESP32的WiFi密码:NVS键值配置工具设计与实现

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 1:02:00 阅读更多 →
芯片封装缺陷检测:扫描声学显微镜(SAT)原理与实操指南

芯片封装缺陷检测:扫描声学显微镜(SAT)原理与实操指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 1:02:00 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/6 7:15:40 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/6 5:29:09 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/6 6:26:51 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/6 8:21:32 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/6 4:21:51 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/6 1:18:13 阅读更多 →