在 Java 中,“网络阻塞”通常指 网络 I/O 操作阻塞了线程,导致程序响应变慢、线程耗尽或卡死。解决思路主要取决于你使用的网络模型和技术栈。下面按常见场景系统说明。
典型阻塞场景:
Socket.accept() 一直等连接InputStream.read() 一直等数据HttpURLConnection 同步请求卡住本质问题:一个线程被“卡在 I/O 上”,不能干别的事。
Socket socket = serverSocket.accept(); // 阻塞
socket.getInputStream().read(); // 阻塞
new Thread(() -> handle(socket)).start();
✅ 简单
❌ 线程爆炸、上下文切换成本高
Selector selector = Selector.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
selector.select();
for (SelectionKey key : selector.selectedKeys()) {
if (key.isAcceptable()) { ... }
if (key.isReadable()) { ... }
}
}
✅ 单线程处理大量连接
✅ 非阻塞
❌ 编程复杂
EventLoopGroup boss = new NioEventLoopGroup();
EventLoopGroup worker = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(boss, worker)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
protected void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new MyHandler());
}
});
✅ 高性能
✅ 自动非阻塞
✅ 支持海量连接
✅ 主流框架(RPC / IM / 网关)
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.getInputStream(); // 阻塞
✅ 解决方式:
OkHttp(异步)WebClient(Spring WebFlux)Apache AsyncHttpClientokHttpClient.newCall(request).enqueue(callback);
很多“阻塞”其实是没设超时。
socket.setSoTimeout(3000);
connection.setConnectTimeout(3000);
connection.setReadTimeout(3000);
✅ 防止永久卡死
✅ 必备配置
ExecutorService pool = Executors.newFixedThreadPool(10);
pool.submit(() -> callRemoteService());
✅ 避免主线程阻塞
❌ 仍是阻塞 I/O,只是隔离了
| 场景 | 推荐 |
|---|---|
| 传统 Web | @Async + 线程池 |
| 高并发 | WebFlux(Reactor) |
| RPC | Netty / gRPC |
jstack 看线程状态(BLOCKED / RUNNABLE)read / accept / connectJava 网络阻塞的本质是线程被 I/O 占用,解决核心是:非阻塞 I/O + 异步 + 超时控制
如果你愿意,可以告诉我:
我可以给你针对性代码方案。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。