惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

GbyAI
GbyAI
Cyberwarzone
Cyberwarzone
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
W
WeLiveSecurity
博客园 - 叶小钗
Hugging Face - Blog
Hugging Face - Blog
Security Latest
Security Latest
Scott Helme
Scott Helme
TaoSecurity Blog
TaoSecurity Blog
N
Netflix TechBlog - Medium
爱范儿
爱范儿
Application and Cybersecurity Blog
Application and Cybersecurity Blog
G
Google Developers Blog
F
Fortinet All Blogs
N
News and Events Feed by Topic
V2EX - 技术
V2EX - 技术
Google Online Security Blog
Google Online Security Blog
L
LINUX DO - 热门话题
NISL@THU
NISL@THU
The GitHub Blog
The GitHub Blog
Spread Privacy
Spread Privacy
S
Secure Thoughts
T
Tailwind CSS Blog
Google DeepMind News
Google DeepMind News
Recorded Future
Recorded Future
N
News and Events Feed by Topic
SecWiki News
SecWiki News
S
Security @ Cisco Blogs
A
About on SuperTechFans
云风的 BLOG
云风的 BLOG
L
Lohrmann on Cybersecurity
P
Palo Alto Networks Blog
Know Your Adversary
Know Your Adversary
IT之家
IT之家
人人都是产品经理
人人都是产品经理
Attack and Defense Labs
Attack and Defense Labs
Hacker News - Newest:
Hacker News - Newest: "LLM"
MyScale Blog
MyScale Blog
宝玉的分享
宝玉的分享
T
The Blog of Author Tim Ferriss
H
Hacker News: Front Page
T
Tenable Blog
C
CERT Recently Published Vulnerability Notes
D
DataBreaches.Net
阮一峰的网络日志
阮一峰的网络日志
Help Net Security
Help Net Security
博客园_首页
S
Securelist
罗磊的独立博客

Java

华为的毕昇 JDK 8 AppCDS 特性稳定吗? - V2EX 我把 Java 开发的 kkRepo 支持 AOT 编译, 1s 极速启动,空闲内存小于 200MB - V2EX fastjson1.x 最新版本疑似又出 RCE 漏洞了 - V2EX 讲讲我怎么获得 kkRepo 的首个企业用户,成功替换掉 Nexus,每年节省 $1,620 PRO 订阅费用 - V2EX Sonatype 正引入 Maven Central 仓库发布使用情况可见性和针对高流量发布活动的限制 - V2EX 让 Java 再次伟大,没有人比我更懂得如何打包!(分享一个四两拨千斤的多 jar 打包 exe 方式) - V2EX 使用 kkRepo 搭建 Maven 私服 - V2EX Nexus 的平替 neuxs-plus 开源涉嫌商标侵权,被迫改名 kkRepo - V2EX 我在 IDEA tab 里养了一只猫 - V2EX Java 确实是内存高效的 用 AI 把 visualvm 的部分功能界面换了个马甲 - V2EX javaer 现在出去面试 问哪些内容 sa-token + spring cloud gateway 过滤器顺序问题 - V2EX 关于在 wsl 中使用 idea 进行 Java 开发的问题 - V2EX 求助, Fortify 漏扫问题解决 - V2EX 微信 ClawBot 和企微 AIBot 的 Java SDK - V2EX 老业务信创重构选型大家有啥建议 - V2EX ai 编程的情况在你们使用什么 IDE - V2EX 下面这段 Java 多态的代码,如何才能改为 Go、 Python 、JS、C++版本? - V2EX JDK 26 发布,非 lts 版本 - V2EX DoytoQuery vs SpringDataJPA - V2EX 求推荐比较优秀的 springboot 脚手架项目 - V2EX vscode 里自用 Java 开发插件:支持复制引用路径、rest 接口路径、Arthas 命令等功能 - V2EX 屎山老项目想用 ai 实现自动化测试,有什么可落地的方案么 - V2EX WebFlux 项目 被访问后 访问方关闭连接 无法捕获 SocketException: Connection reset - V2EX 有人用 RUOYI 框架吗? - V2EX 关于商用 jdk 收费的问题,有遥测吗? - V2EX IDEA 在 macOS 上卡住 - V2EX Java : 2026 年 SpringBoot, Quarkus, Solon ? - V2EX 佬们有没有比较好的 Java 脚手架 - V2EX 一个对比 JavaORM 框架的小仓库 - V2EX 想问一个关于 IO 流的细节 - V2EX 关于我在腾讯云 windows 服务器起了一个后端服务,但是服务器本地都请求不到的问题 11 - V2EX 分享一个 idea 的无响应 bug,如果你也遇到 - V2EX JNI 是否有向"简洁"演化的可能? - V2EX 多实例 springboot 微服务重启时 Counter 类型指标重置问题 - V2EX 讨论个问题:该不该重写 equal 和 hashcode - V2EX 求助 泛型转换碰到一个很奇怪的问题 Object 放 Redis 自动变成 JSONObject 了 - V2EX Java Agent 该怎么快速学习?有教程文档推一下吗? - V2EX 能不能别用那烦人的 MyBatis-Plus 了! - V2EX 作为 Java boy 你们业余时间会学点什么? - V2EX 各位 v 友们!有无无敌好用的剪辑软件求推荐! - V2EX 如何从反射的 Field/Method 动态构造 mybatis 的 SFunction? - V2EX Java 得冗余与啰嗦是不是对 AI 不友好 - V2EX 问一个日志不打印栈信息的问题 - V2EX 为何 RestTemplate 无法定制请求 - V2EX 日经吐槽:现在的 Java 语言真的有点令人恶心 - V2EX 新手 javaer 咨询几个问题 - V2EX 自学 Java 看不懂报错信息和代码,有什么推荐 ai 拿来自学的吗? - V2EX 用 netty 编写代理服务器,切换出口 IP,不能及时生效 - V2EX mysql 慢日志分析排查小工具 1.0.0 - V2EX Preferences.userNodeForPackage(Object.class)存储位置在哪里? - V2EX vscode 中 augment code 怎么使用 mcp - V2EX mysql 慢日志分析排查小工具 - V2EX Java 的一次编译到处运行在目前还有优势吗 - V2EX 现在学 Java 算 49 年入国军吗 - V2EX 推广一下自己刚撸的 IDEA 插件—Bean Copy 助手 - V2EX 几千万的数据量,层级权限下的列表展示页查询应该怎么设计? - V2EX 大家生产环境会一直开着 JFR 吗 - V2EX 有没有新版 Java 的佬(jdk25 和 21 这种), 上手还是走官方文档吗 - V2EX Java 程序员面经怎么准备 - V2EX
自荐 Java 多线程神器——ThreadForge ,让多线程从此简单 - V2EX
HeyHudy · 2026-02-13 · via Java

新春临近,先住各位 V 友新年快乐~

从场景切入

传统的 ExecutorServiceFutureCompletableFuture 非常强大,但写起来比较麻烦:

  • 线程池要手动创建和关闭
  • 超时逻辑每个任务都要写一遍
  • 失败了要不要取消其他任务?得自己判断
  • 异常怎么传播?要么吞掉,要么手动包装
  • 想知道任务跑了多久?自己打日志

我一直在思考怎么能让 Javaer 用多线程的时候能简单点,少点弯弯绕绕,于是诞生了 ThreadForge 。

ThreadForge 的设计哲学很简单:先降低认知成本,再追求性能。

可以把它理解成一个结构化并发框架——让你用写同步代码的思维写并发代码,同时自动处理那些容易遗漏的边界情况。

也可以把它理解成对于 Java 内置并发工具的二次包装,目标是让 Java 并发更简单、更清晰。

什么是结构化?

看一个最简单的例子:

try (ThreadScope scope = ThreadScope.open()) {
    Task<String> user = scope.submit("load-user", () -> fetchUser());
    Task<Integer> orders = scope.submit("load-orders", () -> fetchOrders());
    
    scope.await(user, orders);
    
    // 到这里,两个任务肯定都结束了(成功、失败或超时)
    String result = user.await() + ":" + orders.await();
}
// scope 关闭时,所有任务自动取消、资源自动清理

这段代码有几个关键点:

  1. 所有任务都绑定在 ThreadScope,生命周期有边界,不会泄漏
  2. 默认就是安全的:默认超时、默认失败传播、自动取消
  3. 代码结构就是任务关系:读代码的人一眼就能看出两个任务是并发的,且必须都完成才能继续

对比传统写法,你需要:

  • 创建线程池,配置核心线程数、队列大小
  • 提交任务,手动处理 Future
  • 写 try-finally 确保 shutdown
  • 手动处理超时和异常传播

这里其实就能看出来 ThreadForge 的设计初衷和目标了,就是努力让我们省掉这些重复劳动,专注业务逻辑。

五个让你省脑力的设计

1. 默认行为就是正确的

// 默认:FAIL_FAST + 30 秒超时 + 自动取消其他任务
try (ThreadScope scope = ThreadScope.open()) {
    Task<Integer> a = scope.submit(() -> riskyRpc());
    Task<Integer> b = scope.submit(() -> anotherRpc());
    scope.await(a, b);
} catch (ScopeTimeoutException timeout) {
    // 超时了,所有任务已被自动取消
    fallback();
} catch (FailurePropagationException failed) {
    // 某个任务失败了,其他任务已被自动取消
    handleError(failed);
}

不需要配置,不需要思考,开箱即用。

2. 失败策略明确且统一

不同场景对失败的容忍度不同,ThreadForge 提供了 5 种明确的策略:

  • FAIL_FAST:快速失败,立即取消其他任务(默认)
  • COLLECT_ALL:等所有任务结束,汇总所有失败
  • SUPERVISOR:不自动取消,失败信息收集到 Outcome
  • CANCEL_OTHERS:失败后取消其余任务,但不抛异常
  • IGNORE_ALL:忽略失败,只返回成功的结果
// 场景:批量导入,即使部分失败也要知道哪些成功了
try (ThreadScope scope = ThreadScope.open()
        .withFailurePolicy(FailurePolicy.SUPERVISOR)) {
    
    List<Task<Void>> tasks = ids.stream()
        .map(id -> scope.submit(() -> importData(id)))
        .collect(toList());
    
    Outcome outcome = scope.await(tasks);
    
    // 明确知道哪些成功、哪些失败
    log.info("成功: {}, 失败: {}", 
        outcome.successCount(), outcome.failureCount());
}

3. 并发度控制不再需要手动管理队列

// 场景:调用外部 API,最多同时 50 个请求
try (ThreadScope scope = ThreadScope.open()
        .withConcurrencyLimit(50)) {
    
    List<Task<Result>> tasks = hugeIdList.stream()
        .map(id -> scope.submit(() -> externalApi.call(id)))
        .collect(toList());
    
    List<Result> results = scope.awaitAll(tasks);
}
// 自动限流,不会把外部服务打爆

不需要自己写信号量,也不需要手动分批,框架自动处理。

4. 生命周期观测统一收口

ThreadScope scope = ThreadScope.open()
    .withHook(new ThreadHook() {
        @Override
        public void onStart(TaskInfo info) {
            metrics.taskStarted(info.name());
        }
        
        @Override
        public void onSuccess(TaskInfo info, Duration duration) {
            metrics.taskSuccess(info.name(), duration.toMillis());
        }
        
        @Override
        public void onFailure(TaskInfo info, Throwable error, Duration duration) {
            log.error("Task {} failed after {}", info.name(), duration, error);
            metrics.taskFailed(info.name());
        }
    });

不需要在每个任务里重复写日志和监控代码,同时新的 1.0.2 版本中内置了 ScopeMetricsSnapshot 作为观测点,直接 .toString() 就能看到完整的调用耗时等情况 。

5. 跨 JDK 版本的一致体验

// 同一套 API
try (ThreadScope scope = ThreadScope.open()) {
    // JDK 21+: 自动使用虚拟线程
    // JDK 8-20: 自动降级到线程池
    Task<String> task = scope.submit(() -> longRunningTask());
    return task.await();
}

不需要分叉代码,不需要写 if-else,框架自动适配。

适用场景

ThreadForge 特别适合这些场景:

并发 RPC 聚合

try (ThreadScope scope = ThreadScope.open()) {
    Task<User> user = scope.submit(() -> userService.get(uid));
    Task<List<Order>> orders = scope.submit(() -> orderService.list(uid));
    Task<Profile> profile = scope.submit(() -> profileService.get(uid));
    
    scope.await(user, orders, profile);
    
    return buildResponse(user.await(), orders.await(), profile.await());
}

批量数据处理

try (ThreadScope scope = ThreadScope.open()
        .withConcurrencyLimit(100)
        .withDeadline(Duration.ofMinutes(5))) {
    
    List<Task<Void>> tasks = records.stream()
        .map(r -> scope.submit(() -> process(r)))
        .collect(toList());
    
    scope.awaitAll(tasks);
}

生产者-消费者模式

try (ThreadScope scope = ThreadScope.open()) {
    Channel<Data> channel = Channel.bounded(1000);
    
    scope.submit(() -> {
        for (Data d : datasource) {
            channel.send(d);
        }
        channel.close();
        return null;
    });
    
    List<Task<Void>> consumers = IntStream.range(0, 4)
        .mapToObj(i -> scope.submit(() -> {
            for (Data d : channel) {
                process(d);
            }
            return null;
        }))
        .collect(toList());
    
    scope.awaitAll(consumers);
}

开始使用

Maven:

<dependency>
    <groupId>pub.lighting</groupId>
    <artifactId>threadforge-core</artifactId>
    <version>1.0.2</version>
</dependency>

Gradle:

implementation("pub.lighting:threadforge-core:1.0.2")

最小示例:

try (ThreadScope scope = ThreadScope.open()) {
    Task<String> task = scope.submit(() -> "Hello, ThreadForge");
    System.out.println(task.await());
}

📦 GitHub: github.com/wuuJiawei/ThreadForge
📖 文档: 见项目 docs/api/README.md
📄 License: MIT

最后

感谢所有看到这里的朋友。

JDK21 之后,官方团队也跟进了结构化并发类,可以称这个项目是又一个轮子,也可以称它是在工程化里面的一次探讨和另一种解决方案,毕竟给低版本的 JDK 也提供了可能性。

欢迎点赞、评论,如果有任何问题,也欢迎提出您的宝贵意见。

jimeng-2026-02-10-3757-「 ThreadForge 」 这是我新开发的开源项目,帮我做一个 logo 。Java....png

这是让即梦画的 logo ,看起来有点意思,像是个老派的项目。