Java 中的非阻塞 I/O 模型通常是通过 Java NIO (New I/O) 或 Java NIO 2 (AIO, Asynchronous I/O) 来实现的。
Java NIO 是在 JDK 1.4 中引入的,它使用缓冲区、通道和选择器等概念来提供非阻塞 I/O 操作。以下是一个简单的 Java NIO 示例:
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Iterator;
import java.util.Set;
public class NonBlockingIO {
public static void main(String[] args) throws IOException {
ServerSocketChannel serverSocket = ServerSocketChannel.open();
serverSocket.configureBlocking(false);
serverSocket.socket().bind(8080);
Selector selector = Selector.open();
serverSocket.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
selector.select();
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> it = selectedKeys.iterator();
while (it.hasNext()) {
SelectionKey key = it.next();
it.remove();
if (key.isAcceptable()) {
SocketChannel client = serverSocket.accept();
client.configureBlocking(false);
client.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) {
SocketChannel client = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
while (client.read(buffer) > 0) {
buffer.flip();
// 处理接收到的数据
while (buffer.hasRemaining()) {
System.out.print((char) buffer.get());
}
buffer.clear();
}
}
}
}
}
}
Java NIO 2 是在 JDK 1.7 中引入的,它提供了异步通道和异步文件通道,可以使用回调函数或 Future 对象来处理异步 I/O 操作。以下是一个简单的 Java NIO 2 示例:
import java.io.IOException;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.Future;
public class NonBlockingIO2 {
public static void main(String[] args) throws IOException {
AsynchronousServerSocketChannel server = AsynchronousServerSocketChannel.open();
server.bind(null);
server.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() {
@Override
public void completed(AsynchronousSocketChannel result, Object attachment) {
server.accept(null, this);
// 处理连接
Future<Void> future = result.write(ByteBuffer.wrap("Hello".getBytes()));
future.get(); // 阻塞直到操作完成
try {
result.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void failed(Throwable exc, Object attachment) {
exc.printStackTrace();
}
});
// 在这里,主线程可以继续执行其他任务,因为accept操作是非阻塞的
}
}
在这两个例子中,我们展示了如何设置非阻塞 I/O 操作,注册选择器来监听事件,并在事件发生时处理它们。Java NIO 和 NIO 2 都是基于selector的,selector可以