Java网络IO-BIO
Java BIO 就是传统的 Java I/O 编程
BIO(BlockingI/O):同步阻塞,服务器实现:一个连接一个线程,即客户端有连接请求时服务器端就需要启动一个线程进行处理。
单线程情况下,只有一个线程可以处理客户端请求,也就是同时只能连接一个客户端。
优化点:可以通过线程池机制改善,实现多个客户端连接
BIO 方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中,JDK1.4 以前的唯一选择,程序简单易理解。
示例:使用 Blocking IO 模型实现一个单线程网络服务器
package com.fixbugs.bio;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* Blocking Server
*
* @author fix-bugs
* @date 2023/12/20 17:06
*/
public class BlockingServer {
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(1234);
while (true) {
System.out.println("等待客户端连接...");
Socket clientSocket = server.accept();
System.out.println("新客户端已连接。当前线程ID:" + Thread.currentThread().getId() + ",线程名称:" + Thread.currentThread().getName());
byte[] bytes = new byte[1024];
try(InputStream inputStream = clientSocket.getInputStream();) {
while (true) {
int read = inputStream.read(bytes);
if (read != -1) {
System.out.println("客户端请求数据:" + new String(bytes, 0, read));
} else {
break;
}
}
} finally {
System.out.println("关闭客户端。当前线程ID:" + Thread.currentThread().getId() + ",线程名称:" + Thread.currentThread().getName());
clientSocket.close();
}
}
}
}
输出结果:
等待客户端连接...
新客户端已连接。当前线程ID:1,线程名称:main
客户端请求数据:a
客户端请求数据:b
客户端请求数据:c
客户端请求数据:d
客户端请求数据:d
客户端请求数据:s
客户端请求数据:s
客户端请求数据:1
客户端请求数据:2
关闭客户端。当前线程ID:1,线程名称:main
等待客户端连接...
问题分析:
每个请求都需要创建独立的线程,与对应的客户端进行业务处理,当并发数较大时,需要创建大量线程来处理连接,系统资源占用较大。
连接建立后,如果当前线程暂时没有数据可读,则线程就阻塞在 accept 操作上,造成线程资源浪费。
逃避不一定躲得过,面对不一定最难过