Java为高并发情况限制了非阻塞缓冲区

cn1*_*n1h 8 java collections concurrency buffer guava

基本上我需要一个数据结构来存储服务器端的临时聊天消息.它应该是:

  • 有界:因为我不需要存储太多消息,客户端将发送请求以每秒获取新消息.我认为绑定大小应该是最大值.在一秒钟内挂载并发请求.当缓冲区已满时,将删除旧消息.

  • 适合高并发访问:我不想使用像Collections.synchronizedXXXX这样的数据结构,因为在迭代期间,如果其他线程更改了数据结构,例如添加了一条消息,它将抛出异常,所以我必须锁定整个数据结构,实际上我并不关心客户端请求是否可以获得最后插入的消息,因为它们将在一秒钟后发送新请求,另一方面写操作应该永远不会延迟.包java.util.concurrency下的类似乎是解决方案,但是......

  • 非阻塞:LinkedBlockingQueue,ArrayBlockingQueue它们可以有界并且在迭代期间不会抛出异常,但它们都是阻塞队列.当队列已满时,我想将新元素添加到尾部并从头部删除旧元素而不是阻塞它并等待某人删除标题.

所以我的问题是第三个库有什么好的实现吗?比如谷歌番石榴?或者您可能更了解在服务器上存储临时聊天消息?

非常感谢你!

Fre*_*ger 5

您可以将LinkedBlockingQueue与非阻塞方法offer(或addpoll一起使用并访问它。您可以使用固定容量创建它以使其有界。

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
Run Code Online (Sandbox Code Playgroud)

  • 如果队列未满,即使调用“offer”,“LinkedBlockingQueue”也会获取锁,但它不是免费等待的。 (2认同)

Per*_*ion 4

您可以利用 Apache Commons CircularFifoBuffer。它满足您的第一个和最后一个标准。为了支持并发,您可以将基本缓冲区包装在其同步版本中,如下所示:

Buffer fifo = BufferUtils.synchronizedBuffer(new CircularFifoBuffer());
Run Code Online (Sandbox Code Playgroud)

祝项目顺利。