我有一个基本问题.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 NIO。这是线程正在做的事情:
线程 1:调用选择器的 select() 方法的循环。如果有任何密钥可用,则相应地处理它们。
线程 2:偶尔会通过调用 register() 向选择器注册一个 SocketChannel。
问题是,除非 select() 的超时时间非常小(比如大约 100 毫秒),否则对 register() 的调用将无限期阻塞。即使通道被配置为非阻塞,并且 javadocs 声明 Selector 对象是线程安全的(但它的选择键不是,我知道)。
所以有人对这个问题有什么想法吗?如果我将所有内容都放在一个线程中,该应用程序就可以完美运行。没有问题发生,但我真的很想有单独的线程。任何帮助表示赞赏。我在下面发布了我的示例代码:
将 select(1000) 更改为 select(100) 它将起作用。将其保留为 select() 或 select(1000) ,它不会。
import java.io.IOException;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Iterator;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class UDPSocket
{
private DatagramChannel clientChannel;
private String dstHost;
private int dstPort;
private static Selector recvSelector;
private static volatile boolean initialized;
private static ExecutorService eventQueue = …
Run Code Online (Sandbox Code Playgroud)