8

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

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

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

  • non-blocking: LinkedBlockingQueue, ArrayBlockingQueue 它们可以有界并且在迭代过程中不会抛出异常,但它们都是阻塞队列。当队列已满时,我想将新元素添加到尾部并从头部删除旧元素,而不是在那里阻塞并等待有人删除头部。

所以我的问题是第三个库有什么好的实现吗?例如谷歌番石榴?或者,也许您对在服务器上存储临时聊天消息有更好的想法?

非常感谢!

4

5 回答 5

5

您可以将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
于 2014-10-24T14:58:50.357 回答
4

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

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

祝项目好运。

于 2012-04-13T11:21:04.087 回答
3

你看过ConcurrentLinkedQueue吗?页面说

这个实现采用了一种高效的“无等待”算法......

无等待是您可以获得的最强有力的保证之一......

于 2012-04-12T20:22:35.857 回答
1

ArrayBlockingQueue您可以通过使用条件语句将非阻塞行为添加到 anoffer()中,其中队列无法接受报价会导致头部被丢弃并重新发出报价:

    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++;

        }
    }

    }
于 2014-05-11T21:24:59.603 回答
0

LinkedTransferQueue是一个阻塞的无界队列,不强制执行严格的 FIFO 排序。它只会在从空队列中取出时阻塞,但从不会添加到一个队列中。您可以通过添加大小或读写计数器来添加软上限以逐出元素。

根据您的要求,您可以编写自定义的无锁环形缓冲区。

于 2012-04-13T01:34:40.097 回答