JavaNIO,检查通道是否准备好读、写

JavaNIO,检查通道是否准备好读、写,java,nio,Java,Nio,与通常使用选择器的方式不同,对于每个就绪通道,可以确定并发送消息,我希望选择当前就绪的连接并在那里发送消息 想必这可以通过将所有通道放入选择器进行读取并标记它们准备好读取(如果它们出现),然后对写入进行相同操作,然后从我标记为准备好的通道中进行选择来实现 这是一个好主意吗?有没有更好的方法?我应该注意什么?例如,状态“如果您尝试混合操作读取和操作写入,您将很快陷入麻烦。如果您这样做,Sun Windows实现会死锁。”这里有类似的问题吗?实施以下各项的最佳方式是什么: boolean isRea

与通常使用选择器的方式不同,对于每个就绪通道,可以确定并发送消息,我希望选择当前就绪的连接并在那里发送消息

想必这可以通过将所有通道放入选择器进行读取并标记它们准备好读取(如果它们出现),然后对写入进行相同操作,然后从我标记为准备好的通道中进行选择来实现

这是一个好主意吗?有没有更好的方法?我应该注意什么?例如,状态“如果您尝试混合操作读取和操作写入,您将很快陷入麻烦。如果您这样做,Sun Windows实现会死锁。”这里有类似的问题吗?实施以下各项的最佳方式是什么:

boolean isReadyForRead(SocketChannel c);
boolean isReadyForWrite(SocketChannel c);

当选择器唤醒时,您应该使用SelectionKey来验证套接字是否准备好读取或写入


这是一个非常有用的关于编写NIO服务器和客户端的教程,类似的东西怎么样

public static boolean isReadyForRead(SocketChannel socket) throws IOException {
    return isReady(socket, SelectionKey.OP_READ);
}

public static boolean isReadyForWrite(SocketChannel socket) throws IOException {
    return isReady(socket, SelectionKey.OP_WRITE);
}

public static boolean isReady(SocketChannel socket, int op) throws IOException {
    // Setup
    if (socket.isBlocking()) 
        throw new IllegalArgumentException("Socket must be in non-blocking mode");

    Selector selector = SelectorProvider.provider().openSelector();
    socket.register(selector, op);

    // Real work
    if (selector.selectNow() == 0)
        return false;
    // Just in case selector has other keys
    return selector.selectedKeys().contains(socket.keyFor(selector));
}
此调用效率极低,因为它每次都进行设置。如果您有一个封闭类,应该将其移出。若您知道选择器仅包含一个键,则最后一行可以更改为“
返回true;


我这样做只是为了好玩。我想不出这会有什么用处。Select()旨在高效地告诉您套接字的状态,每个人都应该直接使用它。

我想知道特定频道何时准备就绪,而频道没有.isReadyForRead()方法。Als,“唤醒”是指“当.select()返回时”,还是指线程策略?是指.select()返回时。这是由于连接需要读或写操作,或者调用了selector.select()。然后,您应该遍历选定的键,并验证选择器是否准备好读取或写入。(还有一些其他步骤,但它们都在教程中列出)。@Malaxeur如果
select
返回一个表示可读的SelectionKey,是否可以保证可以从通道中读取字节?这样做是否有任何问题,尽管已移出?(我已经恢复了问题的原始版本。)我不熟悉教程中提到的问题,但我们没有这样做。我们不混合读/写。不会为每次调用更新密钥集,因此不会出现线程问题。