Java Selector 有哪些API操作,给出例子,并写在一个main方法里
时间: 2023-08-31 19:26:18 浏览: 107
### 回答1:
Java Selector 是 Java NIO 包中的一个类,用于多路复用 IO 操作。它可以监听多个通道的 IO 事件,比如读就绪、写就绪等,并且可以通过单线程处理多个通道的 IO 操作,提高了程序的性能。
以下是 Java Selector 的常用 API 操作:
1. open():打开一个 Selector 选择器对象。
2. select():阻塞等待至少一个通道有 IO 事件就绪。
3. selectedKeys():返回所有已经就绪的通道。
4. register():将一个通道注册到 Selector 中,指定监听的事件类型(如 OP_READ、OP_WRITE 等)。
5. keys():返回所有已经注册的通道。
以下是一个使用 Selector 的示例程序,监听两个 SocketChannel 的读事件:
```java
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;
import java.util.Set;
public class SelectorDemo {
public static void main(String[] args) throws IOException {
Selector selector = Selector.open();
// 创建两个 ServerSocketChannel,监听 8080 和 8081 端口
ServerSocketChannel channel1 = ServerSocketChannel.open();
channel1.socket().bind(new InetSocketAddress(8080));
channel1.configureBlocking(false);
channel1.register(selector, SelectionKey.OP_ACCEPT);
ServerSocketChannel channel2 = ServerSocketChannel.open();
channel2.socket().bind(new InetSocketAddress(8081));
channel2.configureBlocking(false);
channel2.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
// 阻塞等待就绪的通道
selector.select();
Set<SelectionKey> readyKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = readyKeys.iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
iterator.remove();
if (key.isAcceptable()) { // 接受连接事件
ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
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(1024);
int len = socketChannel.read(buffer);
if (len > 0) {
buffer.flip();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
System.out.println(new String(bytes));
}
}
}
}
}
}
```
在上面的示例程序中,我们首先打开一个 Selector 对象,然后创建两个 ServerSocketChannel 对象,分别监听 8080 和 8081 端口,并将它们注册到 Selector 中,指定监听的事件类型是 OP_ACCEPT(接受连接事件)。
在 while 循环中,我们调用 select() 方法阻塞等待就绪的通道。当有通道就绪时,会返回一个 SelectionKey 集合,我们可以遍历这个集合,处理每个 SelectionKey 对应的通道的 IO 事件。
在本示例中,我们只监听了读事件(OP_READ),当有数据可读时,会读取数据并打印到控制台。
### 回答2:
Java Selector 是 Java NIO 中的一种选择器,用于监听多个通道的事件,实现非阻塞 I/O。它可以通过 select() 方法来监测一组通道中是否有事件发生,并且提供了一些 API 操作来使用选择器。
Selector 的主要 API 操作如下:
1. open():打开一个 Selector 实例。
2. close():关闭 Selector 实例。
3. select():阻塞并等待注册在该 Selector 上的通道发生事件。
4. selectedKeys():返回当前有事件发生的通道的 SelectionKey 集合。
5. keys():返回注册在该 Selector 上的所有通道的 SelectionKey 集合。
6. wakeup():唤醒 Selector 的 select() 方法。
下面是一个使用 Selector 的简单示例,写在一个 main 方法里:
```java
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
public class SelectorExample {
public static void main(String[] args) throws Exception {
Selector selector = Selector.open(); // 打开一个 Selector
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false); // 设置为非阻塞模式
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); // 注册事件
while (true) {
int readyChannels = selector.select(); // 阻塞并等待事件发生
if (readyChannels == 0) {
continue;
}
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
while (keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
if (key.isAcceptable()) {
// 处理连接请求事件
// ...
} else if (key.isReadable()) {
// 处理读取事件
// ...
} else if (key.isWritable()) {
// 处理写入事件
// ...
}
keyIterator.remove(); // 处理完事件后需要移除 SelectionKey
}
}
selector.close(); // 关闭 Selector
}
}
```
上述示例中,我们首先打开了一个 Selector,然后创建了一个非阻塞的 ServerSocketChannel,并将其注册到 Selector 上,关注 OP_ACCEPT 事件。在主循环中,我们调用 select() 方法进行阻塞,等待事件发生。一旦有事件发生,就遍历 selectedKeys 集合,并根据不同的事件类型进行处理。
需要注意的是,在处理完事件后,需要显式地调用 keyIterator.remove() 方法来移除已经处理完的 SelectionKey。同时,在程序结束时,应当关闭 Selector 以释放资源。
### 回答3:
Java Selector 是Java NIO库中的一个类,它用于实现非阻塞I/O操作。Selector 可以使一个线程同时处理多个通道的 I/O 操作。
Java Selector 提供了以下几个常用的API操作:
1. open():用于创建一个新的 Selector 对象。
2. close():用于关闭 Selector 对象。
3. select():用于等待 I/O 事件的发生。当至少一个通道准备好进行 I/O 操作时,该方法返回。
4. selectedKeys():用于返回一个包含所有已准备就绪的键的集合对象,可以通过迭代器进行遍历。
5. keys():用于返回当前注册到该 Selector 对象的所有键的集合对象。
6. register():用于将通道注册到 Selector 对象,并指定感兴趣的 I/O 事件。可以指定多个 I/O 事件,如 SelectionKey.OP_READ、SelectionKey.OP_WRITE。
下面是一个在main方法中使用 Selector 的例子:
```java
import java.nio.channels.*;
import java.nio.ByteBuffer;
import java.io.IOException;
import java.util.Iterator;
import java.util.Set;
public class SelectorExample {
public static void main(String[] args) throws IOException {
// 创建 Selector
Selector selector = Selector.open();
// 创建通道并注册到 Selector,设置感兴趣的 I/O 事件为读取
SocketChannel socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
SelectionKey selectionKey = socketChannel.register(selector, SelectionKey.OP_READ);
// 等待 I/O 事件的发生
while (true) {
int readyChannels = selector.select();
if (readyChannels == 0) {
continue;
}
// 获取已准备就绪的键集合
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
// 遍历处理已准备就绪的键
while (keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
// 读取事件就绪
if (key.isReadable()) {
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
int bytesRead = channel.read(buffer);
// 处理读取数据...
}
// 写入事件就绪
if (key.isWritable()) {
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
// 写入数据到 buffer...
int bytesWritten = channel.write(buffer);
// 处理写入数据...
}
// 移除已处理的键
keyIterator.remove();
}
}
}
}
```
上述代码中,首先创建了一个 Selector 对象,随后创建了一个非阻塞的 SocketChannel,并将它注册到 Selector 对象中,指定感兴趣的 I/O 事件为读取。然后,在一个无限循环中调用 select() 方法等待 I/O 事件的发生。
一旦有感兴趣的 I/O 事件就绪,通过 selectedKeys() 方法获取已准备就绪的键集合,并对每一个键进行处理,例如读取和写入数据。
最后,通过 keyIterator 的 remove() 方法移除已处理的键。
阅读全文