我有一个基础问题。为什么和怎样可选通道(SelectableChannel)的register方法可以是阻塞调用呢?让我提供一个场景。
我在Register类中创建了一个选择器(Selector)对象,如下所示:
private static Selector selector = Selector.open();
我还有一个在同一类(Register)中的方法注册通道到选择器(selector)。
public static SelectionKey registerChannel(SelectableChannel channel, int ops)
throws IOException {
channel.configureBlocking(false);
return channel.register(selector, ops);
}
还有另一个名为Request的类,它有一种方法可以从通道中读取数据,处理并调用以下方法来注册该通道。
selectonKey = Register.register(socketChannel, SelectionKey.OP_READ);
在这个地方,线程被阻塞了,没有任何提示它在等待什么。我已经确认选择器是开放的。请提供帮助让我了解如何解决这个问题。是否有任何锁可以释放。
任何建议都将不胜感激。
补充我所描述的情况。进一步测试揭示,如果从同一个线程调用Register.register方法,它能够注册,但之后如果其他线程尝试调用该方法,线程就无法继续执行。
select()
中时,有三个嵌套的同步操作,并且register()
尝试其中之一。结果不是死锁而是阻塞,只持续到并发的select()
调用返回为止。解决方法是在register()
之前调用wakeup()
。这会强制select()
解除阻塞并返回零,释放其三个锁,允许register()
获取所需的一个并继续进行。 - user207421select()
返回零,则短暂的休眠就可以解决这个问题。 - user207421