基本上我需要一个数据结构来存储服务器端的临时聊天消息。应该是:
bounded:因为我不需要存储太多消息,客户端会每秒发送一次获取新消息的请求。我认为绑定大小应该是最大值。一秒钟内并发请求的数量。当缓冲区已满时,旧消息将被删除。
适合高并发访问:我不想使用Collections.synchronizedXXXX这样的数据结构,因为在迭代过程中,如果其他线程改变了数据结构,例如添加一条消息,它会抛出一个异常,所以我必须锁定整个数据结构,实际上我并不关心客户端请求是否可以获得最后插入的消息,因为他们会在一秒钟后发送一个新请求,另一方面,写操作应该永远不会延迟。包 java.util.concurrency 下的类似乎是解决方案,但是......
非阻塞:LinkedBlockingQueue、ArrayBlockingQueue它们可以有界,迭代时不会抛出异常,但它们都是阻塞队列。当队列已满时,我想将新元素添加到尾部并从头部移除旧元素,而不是阻塞在那里等待有人移除头部。
所以我的问题是第三库有什么好的实现吗?例如谷歌番石榴? 或者,也许您对在服务器上存储临时聊天消息有更好的想法?
非常感谢!
您可以将LinkedBlockingQueue与非阻塞方法
offer
(或add
)和poll
一起使用来访问它。
您可以使用固定容量创建它以使其有界。
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
您可以使用 Apache Commons CircularFifoBuffer。它符合您的第一个和最后一个标准。为了支持并发,您可以将基本缓冲区包装在它的同步版本中,如下所示:
Buffer fifo = BufferUtils.synchronizedBuffer(new CircularFifoBuffer());
祝项目好运。
您可以通过使用条件
ArrayBlockingQueue
语句将非阻塞行为添加到 offer()
中,其中队列未能接受提议导致 head 被丢弃并重新提出提议:
public class LearnToQueue {
public static void main(String[] args){
Queue<Integer> FIFO = new ArrayBlockingQueue<Integer>(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 排序。它只会在从空队列中取出时阻塞,但不会在添加到一个队列时阻塞。您可以通过添加大小或读写计数器来添加软上限以驱逐元素。
根据您的要求,您可以编写自定义无锁环形缓冲区。