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

时间:2014-04-21 08:32:06

标签: java multithreading nio

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

我不知道如何将读取字节传递给worker并从中获取响应。

现在我正在考虑ByteBuffers的CocurrentQueues将读取数据传递给worker。

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是不安全的(参见出版物专栏)。什么是正确的方法?有没有简单的方法与工人沟通?

1 个答案:

答案 0 :(得分:1)

这样做是安全的。

ConcurrentLinkedQueue提供所有必要的保证:

  

内存一致性效果:与其他并发集合一样,在将对象放入ConcurrentLinkedQueue 之前,线程中的操作发生在之后的操作中,该操作是在另一个集合中从ConcurrentLinkedQueue访问或删除该元素之后发生的线程。