首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何设置Java DelayQueue的容量

如何设置Java DelayQueue的容量
EN

Stack Overflow用户
提问于 2015-04-23 19:29:34
回答 1查看 1.6K关注 0票数 3

我使用LinkedBlockingQueue队列来实现用于TCP/IP事件传输的producer-consumer pattern,我使用的是boolean offer(e),这意味着一旦队列达到其容量,新传入的事件将被忽略(删除)并返回false

现在我必须将事件保存一个可配置的时间(例如2秒),所以我决定使用DelayQueue,它只能在时间过期时保存元素和释放元素。

不幸的是,DelayQueue无界。我想知道是否有一种为DelayQueuedelayQueue.size() == CAPACITY设置容量的方法总是可靠的?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-07 10:16:09

这是一个相当大的问题,因为我们需要访问DelayQueue使用的内部锁,如果我们要将它子类或委托给它,并且锁在DelayQueue中是私有的。

我们不能使用第二个锁,因为这会导致take出现问题。您也许可以自己实现它,但是这样做距离您自己的DelayQueue实现还不止一半,所以这可能不是您想要的。

我们可以使用反射来访问锁。但是,请注意,这不是最好的想法,因为它依赖于DelayQueue的实现细节。它可能不适用于所有的JRE,如果您更改正在运行的JRE版本,它甚至可能失效。也就是说,我认为这是解决你的问题的最简单的方法,尽管有点脏。

代码语言:javascript
复制
/**
 * Bounded implementation of {@link DelayQueue}. This implementation uses
 * reflection to access the internal lock in {@link DelayQueue} so might
 * only work on the Oracle 1.8 JRE.
 * @param <T>
 */
public class BoundedDelayQueue<T extends Delayed> extends DelayQueue<T> {

    // Lock used to synchronize every operation
    private final transient ReentrantLock lock;

    // The limit
    private final int limit;

    BoundedDelayQueue(int limit) {
        try {
            // Grab the private lock in DelayQueue using reflection so we can use it
            // to gain exclusive access outside of DelayQueue
            Field lockField = DelayQueue.class.getDeclaredField("lock");
            lockField.setAccessible(true);
            this.lock = (ReentrantLock) lockField.get(this);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new Error("Could not access lock field", e);
        }
        this.limit = limit;
    }

    @Override
    // All the various ways of adding items in DelayQueue delegate to
    // offer, so we only have to override it and not the other methods
    public boolean offer(final T t) {
        // Lock the lock
        lock.lock();
        try {
            // Check the size limit
            if(size() == limit) {
                return false;
            }
            // Forward to superclass
            return super.offer(t);
        } finally {
            lock.unlock();
        }
    }
}

请注意,如果需要的话,这并不是用超时来实现offer,而是必须自己执行。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29832664

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档