Java nio下的Reactor模式使用示例
时间: 2023-07-20 12:22:42 浏览: 126
Doug Lea Scalable IO in Java
以下是一个基于 Java NIO 的 Reactor 模式示例代码,用于实现网络通信的事件驱动:
```java
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;
public class ReactorExample {
public static void main(String[] args) {
try {
// 创建 ServerSocketChannel 对象并绑定端口
ServerSocketChannel server = ServerSocketChannel.open();
server.socket().bind(new InetSocketAddress(8080));
// 设置非阻塞模式
server.configureBlocking(false);
// 创建 Selector 对象并将 ServerSocketChannel 注册到 Selector 上
Selector selector = Selector.open();
server.register(selector, SelectionKey.OP_ACCEPT);
// 循环等待事件
while (true) {
// 阻塞等待事件
selector.select();
// 获取所有已经就绪的事件
Set<SelectionKey> selectedKeys = selector.selectedKeys();
// 遍历所有已经就绪的事件并处理
Iterator<SelectionKey> iterator = selectedKeys.iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
if (key.isAcceptable()) {
// 处理连接事件
ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
SocketChannel clientChannel = serverChannel.accept();
clientChannel.configureBlocking(false);
clientChannel.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) {
// 处理读取事件
SocketChannel clientChannel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
int bytesRead = clientChannel.read(buffer);
if (bytesRead > 0) {
buffer.flip();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
String message = new String(bytes);
System.out.println("Received message: " + message);
// 将数据回写给客户端
ByteBuffer responseBuffer = ByteBuffer.wrap(("Echo: " + message).getBytes());
clientChannel.write(responseBuffer);
} else if (bytesRead < 0) {
clientChannel.close();
}
}
// 移除已经处理的事件
iterator.remove();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
```
该示例首先创建一个 ServerSocketChannel 对象并绑定到指定端口,然后设置其为非阻塞模式。接着创建一个 Selector 对象,并将 ServerSocketChannel 注册到 Selector 上并指定感兴趣的事件为 OP_ACCEPT。在循环中,通过 Selector 的 select() 方法阻塞等待事件就绪。一旦有事件就绪,通过 Selector 的 selectedKeys() 方法获取所有已经就绪的事件,遍历并处理。对于 OP_ACCEPT 事件,处理连接请求并将新的 SocketChannel 注册到 Selector 上并指定感兴趣的事件为 OP_READ。对于 OP_READ 事件,读取客户端发送的数据并将其回写给客户端。最后移除已经处理的事件。
阅读全文