Java 我们可以使用blockingqueue来实现循环缓冲区吗

Java 我们可以使用blockingqueue来实现循环缓冲区吗,java,Java,需要循环FIFO缓冲区(如果队列已满,则始终删除最早的项),我们可以使用blockingqueue实现它吗?是。见: 公共类ArrayBlockingQueue 扩展抽象队列 实现BlockingQueue,可序列化 有界阻塞队列,由 数组。此队列对元素进行FIFO排序 (先进先出)。头 队列是已启用的元素 排队时间最长。尾巴 队列中的元素具有 排队时间最短。 在尾部插入新元素 以及队列检索 操作从头部获取元素 排队等候 这是一个经典的“有界缓冲区” 一个固定大小的数组可以容纳 制作人插入的元

需要循环FIFO缓冲区(如果队列已满,则始终删除最早的项),我们可以使用blockingqueue实现它吗?

是。见:

公共类ArrayBlockingQueue
扩展抽象队列
实现BlockingQueue,可序列化
有界阻塞队列,由 数组。此队列对元素进行FIFO排序 (先进先出)。头 队列是已启用的元素 排队时间最长。尾巴 队列中的元素具有 排队时间最短。 在尾部插入新元素 以及队列检索 操作从头部获取元素 排队等候

这是一个经典的“有界缓冲区” 一个固定大小的数组可以容纳 制作人插入的元素和 由消费者提取。一旦创建, 容量无法增加。 尝试将一个元素设置为完全 队列将导致put操作 舞台调度;试图检索 空队列中的元素将 类似的块


这可能会有所帮助:这是一个线程安全的解决方案,其中ArrayBlockingQueue用作具有以下约束的环形缓冲区:

  • 生产者:应该始终能够将数据放入缓冲区而不会被阻塞,即使缓冲区已满(即当缓冲区已满时从头部移除!)。 虽然如果我们想让制片人也被封杀,那就直截了当了

  • 使用者:应该能够从输入中获取缓冲区,如果缓冲区为空,则应该被阻止(如果您也希望缓冲区为非阻止缓冲区,则可以使用poll()

    //模拟环形缓冲器

    BlockingQueue<Short[]> bufferQueue = new ArrayBlockingQueue<Short[]>(MAX_SIZE);
    
    Producer Code:
     ...
    //not using put() directly as it can block this thread forever
    if(!bufferQueue.offer(buffer)){
        //retrieve and remove the head of the queue to make space for this buffer
        //don't use take() as it can block this thread again if consumer took all
        //the data before call to take()!
        bufferQueue.poll();
        //now put can be used safely, remember there is only one producer!
        bufferQueue.put(buffer);
    }
    ...
    
    Consumer Code:
    ..
    //this will block till buffer is empty
    //can use .poll() if don't want blocking call
    bufferQueue.take()
    ..
    
    BlockingQueue bufferQueue=new ArrayBlockingQueue(最大大小);
    生产商代码:
    ...
    //不直接使用put(),因为它可能永远阻止此线程
    如果(!bufferQueue.offer(缓冲区)){
    //检索并删除队列头以为该缓冲区腾出空间
    //不要使用take(),因为如果消费者拿走了所有内容,它会再次阻止此线程
    //调用take()之前的数据!
    bufferQueue.poll();
    //现在put可以安全使用,记住只有一个生产商!
    bufferQueue.put(缓冲区);
    }
    ...
    消费者代码:
    ..
    //这将阻塞直到缓冲区为空
    //如果不想阻止调用,可以使用.poll()
    bufferQueue.take()
    ..
    

  • BlockingQueue
    只是一个用于多线程模式的
    队列。为什么不仅仅是一个
    队列
    ?我的问题是,当队列已满时,是否可以将方法放入头部并自动插入尾部?自动:否。但您可以使用
    offer()
    ,如果失败,请自行移除头部并重试。
    BlockingQueue<Short[]> bufferQueue = new ArrayBlockingQueue<Short[]>(MAX_SIZE);
    
    Producer Code:
     ...
    //not using put() directly as it can block this thread forever
    if(!bufferQueue.offer(buffer)){
        //retrieve and remove the head of the queue to make space for this buffer
        //don't use take() as it can block this thread again if consumer took all
        //the data before call to take()!
        bufferQueue.poll();
        //now put can be used safely, remember there is only one producer!
        bufferQueue.put(buffer);
    }
    ...
    
    Consumer Code:
    ..
    //this will block till buffer is empty
    //can use .poll() if don't want blocking call
    bufferQueue.take()
    ..