I'm writing a network server using java.nio selectors. It is designed to get data from network and push it to worker threads, which do some data processing.

I don't know how to pass read bytes to workers and get responses from them.

For now I'm thinking about CocurrentQueues of ByteBuffers to pass read data to workers.

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
        ...
    }
    ...  
}

It looks like it is not safe to publish ByteBuffer this way (see publication line). What is a proper way? Is there any easy way to communicate with workers?

有帮助吗?

解决方案

It's safe to do it this way.

ConcurrentLinkedQueue provides all necessary guarantees:

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.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top