Java NIO和BIO的区别
Java NIO(New Input/Output)和BIO(Blocking Input/Output)是Java中两种不同的I/O处理方式。它们在处理数据的方式、性能、适用场景等方面有显著的区别。下面将详细介绍这两者的区别。
BIO(Blocking I/O):
NIO(Non-blocking I/O):
特性 | BIO | NIO |
---|---|---|
阻塞性 | 阻塞式 | 非阻塞式 |
线程模型 | 每个连接一个线程 | 一个线程可以管理多个连接 |
性能 | 在高并发情况下性能较差 | 在高并发情况下性能较好 |
适用场景 | 适合小型应用或连接数较少的场景 | 适合高并发、大规模的网络应用 |
API | java.io包 | java.nio包 |
数据传输方式 | 字节流和字符流 | 通道(Channel)和缓冲区(Buffer) |
import java.io.*;
import java.net.*;
public class BioServer {
public static void main(String[] args) throws IOException {
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("BIO Server started...");
while (true) {
Socket socket = serverSocket.accept(); // 阻塞等待连接
new Thread(new ClientHandler(socket)).start(); // 为每个连接创建一个新线程
}
}
}
class ClientHandler implements Runnable {
private Socket socket;
public ClientHandler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try (BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {
String line;
while ((line = in.readLine()) != null) {
System.out.println("Received: " + line);
out.println("Echo: " + line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
public class NioServer {
public static void main(String[] args) throws IOException {
Selector selector = Selector.open();
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.bind(new InetSocketAddress(8080));
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("NIO Server started...");
while (true) {
selector.select(); // 阻塞,直到有事件发生
Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
while (keys.hasNext()) {
SelectionKey key = keys.next();
keys.remove();
if (key.isAcceptable()) {
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) {
SocketChannel socketChannel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(256);
int bytesRead = socketChannel.read(buffer);
if (bytesRead == -1) {
socketChannel.close();
} else {
buffer.flip();
socketChannel.write(buffer); // Echo back
}
}
}
}
}
}
在选择使用BIO还是NIO时,应根据具体的应用需求和场景来决定。