我有一个基本问题.SelectableChannel的寄存器方法为何以及如何阻止调用.让我提供一个场景.
我在类Register中创建了一个Selector对象,如下所示.
private static Selector selector = Selector.open();
Run Code Online (Sandbox Code Playgroud)
我在同一类(寄存器)中也有一个方法用选择器注册通道.
public static SelectionKey registerChannel(SelectableChannel channel, int ops)
throws IOException {
channel.configureBlocking(false);
return channel.register(selector, ops);
}
Run Code Online (Sandbox Code Playgroud)
还有另一个名为Request的类,它具有从通道,进程和调用方法中读取数据以注册通道的方法.
selectonKey = Register.register(socketChannel, SelectionKey.OP_READ);
Run Code Online (Sandbox Code Playgroud)
在这一点上,线程被阻塞,没有提供它正在等待的线索.我已经确认选择器已打开.请帮助我了解如何解决此问题.我可以释放任何锁吗?
任何输入将不胜感激.
添加到我描述的内容中.进一步的测试显示,如果从同一个线程调用Register.register方法,它可以注册,但在此之后,如果其他一些线程尝试调用该方法,则线程不会继续前进.
我有一个Thread私有Selector和公共register(SelectableChannel channel, ...)方法的子类,允许其他线程将通道注册到选择器.
正如这里所回答的那样,register()选择器中的通道阻塞select()/ select(long timeout)所以我们需要wakeup()选择器.
我的线程无限期地选择(除非它被中断)并且它实际上设法在register()调用通道之前进入下一个选择.所以我认为我使用一个带synchronized块的简单锁来确保register()首先发生.
代码:(为了便于阅读,删除了不相关的代码)
public class SelectorThread extends Thread {
...
public void register(SelectableChannel channel, Attachment attachment) throws IOException {
channel.configureBlocking(false);
synchronized (this) { // LOCKING OCCURS HERE
selector.wakeup();
channel.register(selector,
SelectionKey.OP_READ,
attachment);
}
}
@Override
public void run() {
int ready;
Set<SelectionKey> readyKeys;
while (!isInterrupted()) {
synchronized (this) {} // LOCKING OCCURS HERE
try { …Run Code Online (Sandbox Code Playgroud)