Reputation: 2254
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?
Upvotes: 0
Views: 217
Reputation: 242686
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.
Upvotes: 1