如何同时读取多个 InputStream 并执行其他任务
作者:WarmHope
时间:2026-07-05
浏览:0
Java中直接使用BufferedReader.lines().forEach()读取输入流会阻塞主线程,导致后续任务无法执行。正确做法是为每个流分配独立线程,采用readLine()逐行读取,并通过ExecutorService管理线程生命周期。避免重复创建流对象,必要时可包装流以支持超时。
本文目录
在 Ja va 中,直接使用 `BufferedReader.lines().forEach()` 来消费行数据,这其实是一个典型的“阻塞陷阱”。很多开发者初次接触时都会被它坑一把——因为 `forEach()` 会一口气消费整个流(Stream),而这个流是惰性求值的,它不会主动停止。这意味着,只要输入流没有关闭(比如进程没退出、socket 没断开),它就一直在那里等着,后续代码自然也就失去了执行机会。
你看到的“this never runs”输出,就是这种情况:`br.lines().forEach(...)` 在第一个流无数据时无限挂起,主线程被卡死,后面的逻辑根本轮不到执行。
所以,想要同时处理多个 InputStream 并执行其他任务,关键是理解一个基本事实:**I/O 操作本质上是阻塞的,你不可能在一个线程里通过“伪并发”绕过它。** 代码里那种“在单线程里用函数式流 API 一次性消费整个输入流”的做法,注定行不通。
本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com

几个关键要点
- `readLine()` 是逐行阻塞的,不是批量阻塞。每次只等待一行数据,这让你能更灵活地响应中断或配合超时控制。 - 使用 `ExecutorService` 统一管理线程,避免手动创建和销毁线程带来的麻烦,也防止资源泄漏。 - 需要特别提醒的是,`InputStream` 本身不原生支持超时。如果某个流长期没有数据,想要“及时放弃”,可以将其包装为 `ja va.nio.channels.Channels.newChannel(in)` 并配合 Selector(适用于 `ReadableByteChannel`)。不过,对于普通的 Process 或 Socket 输入流,更实用的做法是确保源头(如子进程)能在合适的时候正常关闭流。 - 另外,绝对不要像原代码那样,在循环内部重复创建 `InputStreamReader` / `BufferedReader`。这不仅效率极低,更危险的是,之前的流对象可能已经被消费,导致数据丢失。 说到底,Ja va 里并发读取多个 InputStream 的标准化解法,说穿了就是四个字:**一线一程**。再配合 `readLine` 循环,而不是在单线程里用函数式流 API 强撑“伪并发”。多线程不是权宜之计,而是 I/O 并发场景下合理且必要的设计模式。
作者最新文章
sql条件判断字符串不包含某个字符串的方法详解
2026-10-13 17:39
漫蛙漫画官网
2026-10-13 13:19
漫蛙官网入口免费下载安装最新版
2026-10-13 13:18
漫蛙漫画登录页面在哪
2026-10-13 13:15
Photoshop自定义图层样式的保存、导入与管理技巧
2026-10-05 14:17
热门文章
更多
精品专题
更多
Mac软件
更多
WINDOWS
更多










































