java - 安全地将 ByteBuffer 发布到工作线程

标签 java multithreading nio

我正在使用 java.nio 选择器编写网络服务器。它的设计目的是从网络获取数据并将其推送到工作线程,工作线程进行一些数据处理。

我不知道如何将读取的字节传递给工作人员并从他们那里获取响应。

现在我正在考虑使用 ByteBuffers 的 CocurrentQueues 将读取的数据传递给工作人员。

while(keyIterator.hasNext()) {
    SelectionKey key = keyIterator.next();
    keyIterator.remove();

    if(!key.isValid())
        continue;
    if(key.isAcceptable()) {
        accept...
        ConcurrentLinkedQueue<ByteBuffer> queue = new ConcurrentLinkedQueue<>();
        key.attach(queue);
        pushToWorker(queue);
    }
    if(key.isReadable()) {
        ByteBuffer buffer = ByteBuffer.allocate(4096);
        SocketChannel clientsc = (SocketChannel) key.channel();
        clientsc.read(buffer);
        ConcurrentLinkedQueue queue = (ConcurrentLinkedQueue) key.attachment();
        queue.offer(buffer); //publication
        ...
    }
    ...  
}

看起来以这种方式发布 ByteBuffer 并不安全(请参阅发布行)。什么才是正确的方法呢?有什么简单的方法可以与 worker 沟通吗?

最佳答案

这样做是安全的。

ConcurrentLinkedQueue提供所有必要的保证:

Memory consistency effects: As with other concurrent collections, actions in a thread prior to placing an object into a ConcurrentLinkedQueue happen-before actions subsequent to the access or removal of that element from the ConcurrentLinkedQueue in another thread.

关于java - 安全地将 ByteBuffer 发布到工作线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23193749/

相关文章:

java - FileChannel.force 和 FileDescriptor.sync 都需要吗?

java - 安卓和Java : use of runnable

java - MATLAB - 删除二进制文件的元素而不加载整个文件

java - 使用Thread.currentThread()。isInterrupted()与Thread.sleep()

java - Java.NIO 中顺序 channel 写入发送损坏的数据

java - Java中的多线程服务器

来自 null 泛型类型的 Java 泛型数组

java - Spring MVC。方法参数字段的默认值

c++ - QtWebEngine - 同步执行 JavaScript 以读取函数结果

java - 为什么 ExecutorService.submit(Runnable task) 返回 Future<?> 而不是 Future<Void>?