Java 1.3 時代實現高併發服務器只有兩條路:多線程(一連接一線程)或第三方庫。前者線程管理複雜、上下文切換開銷大;後者引入外部依賴。JDK 1.4 (JSR 51) 引入 New I/O (NIO),核心是非阻塞套接字,允許單線程管理成千上萬連接。
ByteBuffer、CharBuffer 等七種基本類型對應)。position(讀寫位置)、limit(邊界)、capacity(容量)。put() 寫入、get() 讀取、flip() 切換讀寫模式、clear() 重置、allocateDirect() 分配堆外內存(零拷貝潛力)。SocketChannel、ServerSocketChannel 替代傳統 Socket。configureBlocking(false)。channel.read(buffer)、channel.write(buffer)。OP_ACCEPT、OP_CONNECT、OP_READ、OP_WRITE。select() 阻塞直到有事件,返回就緒鍵集合 selectedKeys()。SelectionKey 封裝 Channel、事件類型、附件。ServerSocketChannel server = ServerSocketChannel.open();
server.configureBlocking(false);
server.socket().bind(new InetSocketAddress(8000));
Selector selector = Selector.open();
server.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
selector.select(); // 阻塞等待事件
for (SelectionKey key : selector.selectedKeys()) {
if (key.isAcceptable()) {
SocketChannel client = server.accept();
client.configureBlocking(false);
client.register(selector, SelectionKey.OP_READ); // 註冊讀事件
} else if (key.isReadable()) {
SocketChannel client = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(32);
client.read(buffer);
buffer.flip();
// 解碼處理...
}
// 處理完必須 key.cancel() 或 iterator.remove()
}
}
客戶端註冊 OP_CONNECT,連接成功後註冊 OP_WRITE 循環發送數據。演示多客戶端交錯發送,服務端單線程交錯處理,證明非阻塞特性。
flip() 切換讀模式,讀完 clear() 或 compact() 重置。CharsetDecoder/Encoder 處理字節↔字符轉換(如 ISO-8859-1)。NIO 非阻塞套接字是 Java 高性能網絡編程的里程碑。無需手動管理線程池,單線程即可支撐萬級併發連接,為 Netty、Mina 等高性能網絡框架奠定基礎。