Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如果已满,则从ArrayBlockingQueue中逐出对象_Java_Multithreading_Guava_Blockingqueue - Fatal编程技术网

Java 如果已满,则从ArrayBlockingQueue中逐出对象

Java 如果已满,则从ArrayBlockingQueue中逐出对象,java,multithreading,guava,blockingqueue,Java,Multithreading,Guava,Blockingqueue,我使用的是ArrayBlockingQueue,但有时它会变满,并阻止向其中添加其他对象 我想做的是删除队列中最旧的对象,然后在ArrayBlockingQueue满时添加另一个对象。我需要ArrayBlockingQueue像番石榴驱逐队列,但线程安全。我打算扩展ArrayBlockingQueue并覆盖offer(E)方法,如下所示: public class MyArrayBlockingQueue<E> extends ArrayBlockingQueue<E>

我使用的是ArrayBlockingQueue,但有时它会变满,并阻止向其中添加其他对象

我想做的是删除队列中最旧的对象,然后在ArrayBlockingQueue满时添加另一个对象。我需要ArrayBlockingQueue像番石榴驱逐队列,但线程安全。我打算扩展ArrayBlockingQueue并覆盖offer(E)方法,如下所示:

public class MyArrayBlockingQueue<E> extends ArrayBlockingQueue<E> {

// Size of the queue
private int size;

// Constructor
public MyArrayBlockingQueue(int queueSize) {

    super(queueSize);
    this.size = queueSize;
}

@Override
synchronized public boolean offer(E e) {

    // Is queue full?
    if (super.size() == this.size) {
        // if queue is full remove element 
        this.remove();
    }
    return super.offer(e);
} }
公共类MyArrayBlockingQueue扩展了ArrayBlockingQueue{
//队列的大小
私有整数大小;
//建造师
公共MyArrayBlockingQueue(int queueSize){
超级(队列大小);
this.size=队列大小;
}
@凌驾
同步公共布尔报价(E){
//排满了吗?
if(super.size()==此.size){
//如果队列已满,请删除元素
这个。删除();
}
返回超级报价(e);
} }
上述方法行吗?还是有更好的方法

谢谢当你说“它已满并阻止添加其他对象”时,这是否意味着它足以确保可以随时添加对象?如果这是真的,您可以简单地切换到一个无界队列,例如。但请注意与
阵列锁定队列相比的差异:

链接队列通常比基于阵列的队列具有更高的吞吐量,但在大多数并发应用程序中性能不太可预测


您可以找到JDK队列实现的概述。

您的
MyArrayBlockingQueue
不会覆盖
BlockingQueue.offer(E,long,TimeUnit)
BlockingQueue.poll(long,TimeUnit)
。您真的需要具有“阻塞”功能的队列吗?如果您不这样做,则可以使用以下方法创建一个由支持的线程安全队列:

对于逐出阻塞队列,我发现您建议的实现存在一些问题:

  • remove()
    如果队列为空,则可能引发异常。您的
    offer
    方法标记为
    synchronized
    ,但是
    poll
    remove
    等不是这样的,因此另一个线程可能会在调用
    size()
    remove()
    之间耗尽您的队列。我建议改用不会引发异常的
    poll()
  • 您对
    offer
    的调用仍然可能返回
    false
    (即,不“添加”元素),因为另一个竞争条件,在检查大小和/或删除元素以减小大小之间,另一个线程会添加一个填充队列的元素。我建议对
    offer
    的结果使用循环关闭,直到返回
    true
    (见下文)
  • 调用
    size()
  • 我相信以下实施将为您带来您想要的:

    public class EvictingBlockingQueue<E> extends ArrayBlockingQueue<E> {
        public EvictingBlockingQueue(int capacity) {
            super(capacity);
        }
    
        @Override
        public boolean offer(E e) {
            while (!super.offer(e)) poll();
            return true;
        }
    
        @Override
        public boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException {
            while (!super.offer(e, timeout, unit)) poll();
            return true;
        }
    }
    
    公共类退出BlockingQueue扩展了ArrayBlockingQueue{
    公共逐出阻塞队列(整数容量){
    超级(容量);
    }
    @凌驾
    公共布尔报价(E){
    而(!super.offer(e))poll();
    返回true;
    }
    @凌驾
    公共布尔提供(E、长超时、时间单位)抛出InterruptedException{
    而(!super.offer(e,timeout,unit))poll();
    返回true;
    }
    }
    

    请注意,如果在对
    super.offer(E)
    的两次调用之间,另一个线程删除一个元素,则此实现可能会不必要地删除该元素。这对我来说似乎是可以接受的,但我并没有看到一种切实可行的解决方法(
    ArrayBlockingQueue.lock
    是包私有的,
    java.util.concurrent
    是禁止的包,所以我们不能在那里放置一个实现来访问和使用锁等)。

    Hi mfulton26。我的错误是,我仍然想要一个具有阻塞功能的队列。你是说一个Queues.synchronizedQueue(executingQueue.create(maxSize));会有阻塞吗?@user1982350我已经更新了我的答案,以解决驱逐阻塞队列的需要。谢谢mfulton26。我要试一试。我发现令人惊讶的是,没有人编写一个BlockingQueue,在一定时间后自动从自身移除对象。理想情况下,我只需要一个ArrayBlockingQueue来跟踪对象在队列中的时间。一旦过了一定的时间,就把旧东西扔掉。我会尝试你的解决方案。我想到了,但我也在努力避免对象在队列中停留太长时间。这就是为什么我要删除队列头部的对象,以便为要添加到尾部的下一条消息腾出空间。我需要在队列已满时逐出一条消息,并保留对ArrayBlockingQueue的阻塞。看来番石榴驱逐队可以完成这项工作。
    public class EvictingBlockingQueue<E> extends ArrayBlockingQueue<E> {
        public EvictingBlockingQueue(int capacity) {
            super(capacity);
        }
    
        @Override
        public boolean offer(E e) {
            while (!super.offer(e)) poll();
            return true;
        }
    
        @Override
        public boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException {
            while (!super.offer(e, timeout, unit)) poll();
            return true;
        }
    }