- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 ArrayBlockingQueue,但有时它会变满并阻止向其中添加其他对象。
我想做的是在 ArrayBlockingQueue 变满时删除队列中最旧的对象,然后再添加另一个对象。我需要 ArrayBlockingQueue 像 Guava EvictingQueue 但线程安全。我打算扩展 ArrayBlockingQueue 并覆盖 offer(E 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
不会覆盖 BlockingQueue.offer(E, long, TimeUnit)
或 BlockingQueue.poll(long, TImeUnit)
。您真的需要具有“阻塞”功能的队列吗?如果你不这样做,那么你可以创建一个由 EvictingQueue
支持的线程安全队列。使用 Queues.synchronizedQueue(Queue)
:
Queues.synchronizedQueue(EvictingQueue.create(maxSize));
对于逐出阻塞队列,我发现您提议的实现存在一些问题:
remove()
可能会抛出异常。您的 offer
方法标有 synchronized
但 poll
、remove
等不是,因此另一个线程可能耗尽您的资源在调用 size()
和 remove()
之间排队。我建议改用 poll()
,这样不会抛出异常。offer
的调用可能仍会返回 false
(即不“添加”元素),因为在检查大小和/或删除元素之间存在另一个竞争条件为了减小大小,不同的线程添加了一个填充队列的元素。我建议对 offer
的结果使用循环,直到返回 true
(见下文)。size()
、remove()
和 offer(E)
都需要一个锁,因此在最坏的情况下,您的代码会锁定并解锁 3 次(即使如此,由于前面描述的问题,它也可能无法按预期运行)。我相信下面的实现会让你得到你想要的:
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;
}
}
请注意,如果在两次调用 super.offer(E)
之间另一个线程删除了一个元素,则此实现可能会不必要地删除一个元素。这对我来说似乎可以接受,我并没有真正看到解决它的实用方法(ArrayBlockingQueue.lock
是包私有(private)的,java.util.concurrent
是一个禁止包所以我们不能在那里放置一个实现来访问和使用锁等)。
关于java - 如果已满,则从 ArrayBlockingQueue 中逐出对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41036531/
我编写了一个函数来包含两个 DateTime 之间的小时列表。 但最后它看起来并不是很容易阅读,这让我想对它进行单元测试,即使我正在从事的项目根本没有进行单元测试。 所以我的问题是,是否有一种更易读或
我一定是漏掉了什么,因为我还没有在网上找到这个非常基本的问题的答案。我正在使用能够容纳三个 int 的缓冲 channel 值。 然后我使用三个 goroutine 来填充它,一旦缓冲 channel
我发现如果一个矩阵(几乎)满了,那么将它存储在稀疏中会导致(更多)更多的计算时间。 虽然以稀疏形式存储完整矩阵是微不足道的,但我只想知道这一事实背后的原因。 我的推测是稀疏索引读取将是计算时间的主要贡
root@root:~# sudo du -ch --max-depth=1 --exclude=/home/ / du: cannot access ‘/sys/kernel/slab/L2TP/I
基本上我想创建一个 UIProgressView 在 3 秒内从 0.0(空)到 1.0(满)。有人能指出我在 swift 中使用 NSTimer 与 UIProgressView 的正确方向吗? 最
我是一名优秀的程序员,十分优秀!