Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java bounded non-blocking buffer for high concurrent situation

Basically I need a data structure to store the temporary chatting messages on the server side. It should be:

  • bounded: because I don't need store too many messages, the client will send request to get the new messages every second. I think the bound size should be the max. mount of concurrent requests in one second. When the buffer is full, the old messages will be removed.

  • suitable for high concurrent access: I don't want to use the data structure like Collections.synchronizedXXXX, because during the iteration, if other thread changes the data structure, e.g. adds a message, it will throw an Exception, so I have to lock the whole data structure, actually I don't really care if the client request can get the most last inserted message, because they will send a new request after one second, on the other side the write operation should be never delayed. The classes under the package java.util.concurrency seems the solution, but...

  • non-blocking: LinkedBlockingQueue, ArrayBlockingQueue they could be bounded and won't throw exception during iteration, but they are all blocking queue. When the queue is full, I want to add the new element to the tails and remove the old element from head instead of blocking there and wait for someone to remove the header.

So my question is there any good implementation from 3rd library? For example Google Guava? Or maybe you have better idea about storing the temporary chatting messages on server?

thank you very much!

like image 860
cn1h Avatar asked Apr 12 '12 19:04

cn1h


2 Answers

You can use LinkedBlockingQueue with the non-blocking methods offer (or add) and poll to access it. You can create it with a fixed capacity to make it bounded.

LinkedBlockingQueue<String> myStrings = new LinkedBlockingQueue<String>(100);
myStrings.offer("Hi!"); // returns false if limit is reached
myStrings.add("Hi, again!"); // throws exception if limit is reached
String s = myStrings.poll(); // returns null if queue is empty
like image 95
Frederic Leitenberger Avatar answered Sep 24 '22 02:09

Frederic Leitenberger


You could utilize the Apache Commons CircularFifoBuffer. It meets your first and last criteria. To support concurrency, you can wrap the base buffer in it's synchronized version like so:

Buffer fifo = BufferUtils.synchronizedBuffer(new CircularFifoBuffer());

Good luck on the project.

like image 43
Perception Avatar answered Sep 26 '22 02:09

Perception