相关疑难解决方法(0)

调用select()时,Java节点在使用选择器注册通道时阻塞.该怎么办?

我有一个基本问题.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方法,它可以注册,但在此之后,如果其他一些线程尝试调用该方法,则线程不会继续前进.

java multithreading deadlock nio

14
推荐指数
3
解决办法
8065
查看次数

NIO选择器:如何在选择时正确注册新频道

我有一个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)

java multithreading nio

10
推荐指数
2
解决办法
5476
查看次数

标签 统计

java ×2

multithreading ×2

nio ×2

deadlock ×1