Java为高并发情况限制了非阻塞缓冲区
基本上我需要一个数据结构来存储服务器端的临时聊天消息。 它应该是:
-
有界:因为我不需要存储太多消息,客户端将每秒发送请求以获取新消息。 我认为绑定的大小应该是最大值。 在一秒钟内挂载并发请求。 当缓冲区已满时,将删除旧消息。
-
适合高并发访问:我不想使用像Collections.synchronizedXXXX这样的数据结构,因为在迭代期间,如果其他线程更改了数据结构,例如添加了一条消息,它将抛出exception,所以我必须锁定整个数据结构,实际上我并不关心客户端请求是否可以获得最后插入的消息,因为它们将在一秒后发送新请求,另一方面写操作应该永远不会延迟。 包java.util.concurrency下的类似乎是解决方案,但是……
-
非阻塞:LinkedBlockingQueue,ArrayBlockingQueue它们可以是有界的,并且在迭代期间不会抛出exception,但它们都是阻塞队列。 当队列已满时,我想将新元素添加到尾部并从头部删除旧元素而不是阻塞它,并等待某人删除标题。
所以我的问题是第三个库有什么好的实现吗? 比如谷歌番石榴? 或者您可能更了解在服务器上存储临时聊天消息?
非常感谢你!
您可以使用Apache Commons CircularFifoBuffer 。 它符合您的第一个和最后一个标准。 要支持并发,可以将基本缓冲区包装在其同步版本中,如下所示:
Buffer fifo = BufferUtils.synchronizedBuffer(new CircularFifoBuffer());
祝这个项目好运。
您可以使用LinkedBlockingQueue和非阻塞方法offer
(或add
)和poll
来访问它。 您可以使用固定容量创建它以使其有界。
LinkedBlockingQueue myStrings = new LinkedBlockingQueue (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
你看过ConcurrentLinkedQueue了吗? 该页面说
该实现采用有效的“等待”算法……
等待自由是你可以获得的最强保证之一….
您可以通过使用条件offer()
语句将其包含在ArrayBlockingQueue
来添加非阻塞行为,其中接受该报价的队列失败会导致磁头被删除并且要求重新提供:
public class LearnToQueue { public static void main(String[] args){ Queue FIFO = new ArrayBlockingQueue (4); int i = 0; while ( i < 10 ){ if (!FIFO.offer(i)){ // You can pipe the head of the queue anywhere you want to FIFO.remove(); FIFO.offer(i); } System.out.println(FIFO.toString()); i++; } } }
LinkedTransferQueue是一个阻塞的无界队列,不强制执行严格的FIFO排序。 它只会在从空队列中获取时阻止,但从不添加到一个队列。 你可以添加一个软帽来通过添加一个大小或读写计数器来驱逐元素。
根据您的要求,您可以编写自定义无锁环缓冲区。
- Guava EventBus中的注释与接口
- Java 8是否缓存了对供应商的支持?
- Java:取消装箱整数时的空指针exception?
- Java 8流字符串空或空filter
- 为什么Guava类提供了如此多的工厂方法而不是只提供varargs的方法?
- 如何比较两个MultiMaps?
- Guava-11.0.2.jar与com.google.common_1.0.0.0_0-6.jar有冲突吗?
- google common cache – maximumSize的默认值(和其他“可选”设置) – 想要一个使用所有“可用”内存的缓存
- 为什么it.next()抛出java.util.ConcurrentModificationException?