我正在编写另一个 NIO 服务器。有一个选择器线程执行读取、处理(大多数情况下)和写入(下面的伪代码,不是真正的 Java):
while (true) {
select();
for (key : keys) {
if (isReading(key)) {
data = read(key.channel());
result = process(data);
key.interestOps(OP_WRITE);
}
if (isWriting(key)) {
key.channel().write(result);
}
}
}
大多数情况下的处理是微不足道的,所以应该没问题。但是,有(极少数)情况下,处理是耗时的,应该委托给另一个线程。因此,该线程应该以某种方式告诉选择器在处理完成时对 OP_WRITE 感兴趣。
正如我所见,至少有两种方法可以做:
- 调用 wakeup() 和 register() 以使用同步在同一(工作)线程中进行写入,以防止下一个 select() 发生而不导致 register() 挂起。
- 将“注册”操作入队,然后在工作线程中调用 wakeup() 以允许选择器线程将操作出列以注册以在同一线程中写入。
我的问题是:如果我选择方法#2,我是否必须使用线程安全的队列实现(比如 ConcurrentLinkedQueue)?我怀疑我不会因为 enqueue() “之前发生” dequeue() 这是由 wakeup() 调用保证的,但我无法正式证明这一点。
请帮忙!谢谢!