java - Selector.wakeup()和 "happens-before"的关系

标签 java selector wakeup

我正在编写另一个 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);
        }
    }
}

大多数情况下的处理都很简单,所以应该没问题。然而,在某些(罕见)情况下,处理非常耗时,应该委托(delegate)给另一个线程。因此,该线程应该以某种方式告诉选择器在处理完成时对 OP_WRITE 感兴趣。

据我所知,至少有两种方法可以实现:

  1. 使用同步在同一(工作)线程中调用wakeup()和register()进行写入,以防止下一个select()发生,从而不会导致register()挂起。
  2. 将“注册”操作加入队列,然后在工作线程中调用wakeup(),以允许选择器线程将操作出列,以便在同一线程中进行注册写入。

我的问题是:如果我选择方法 #2,我是否必须使用线程安全队列实现(例如 ConcurrentLinkedQueue)?我怀疑我不知道,因为 enqueue() “发生在” dequeue() 之前,这是由wakeup() 调用保证的,但我无法正式证明这一点。

请帮忙!谢谢!

最佳答案

根据我的评论,你的问题是基于一个谬论。您不需要“在处理完成时告诉选择器对 OP_WRITE 感兴趣”。您只需在创建响应后编写响应即可。只有在写入返回零的情况下,才有必要让选择器对 channel 的 OP_WRITE 感兴趣。

为了回答您的补充问题,select() 参与三个已记录的同步级别。 wakeup() 不会,但您通常会在 wakeup() 之后使用选择器上同步的 block ,在该 block 中您可以使用选择器下次选择时需要了解的任何内容。这完成了所有必要的先发生关系。

关于java - Selector.wakeup()和 "happens-before"的关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28754275/

相关文章:

Java : URLConnection setRequestProperty range issue relying on multithreaded process?

css - selenium xpath 获取没有关联 id 的元素的值

从未选择用于多个 OP 代码的 Java SocketChannel register()

android - 即使手机被锁定,如何每 x 分钟发送一次通知

serial-port - 通过 RS232 将 PIC16F1825 从 sleep 状态唤醒

java - JButton双击出现新线程,为什么会出现这种情况

Java:比较字符串时 != 的等价物是什么?

java - 如何检查当前方法的参数是否具有注释并在 Java 中检索该参数值?

html - sIFR 3 - 选择器