【问题标题】:Is there an opposite for the DelayQueue?DelayQueue 有相反的情况吗?
【发布时间】:2015-04-01 13:11:35
【问题描述】:

我需要一个能够自动删除超过给定毫秒数的元素的队列 - 基本上,我希望队列中的项目在一段时间后过期。

我看到有一个延迟队列似乎在做相反的事情:“一个元素只能在它的延迟过期时被取走。” (我没用过)。

也许有一个队列实现可以满足我的需要?如果有界就更好了。

【问题讨论】:

    标签: java queue


    【解决方案1】:

    这样做的问题是此时将删除已过期的元素。如果您担心队列的大小没有超出特定限制,您将必须有一个单独的“更清洁”线程,在它们过期时从队列中删除它们。您可以使用DelayQueue 来实现它(offer 将添加到内部LinkedHashSetDelayQueuepoll 在集合上运行,另外还有一个更清洁的线程轮询DelayQueue,并从集合,因为它们“成熟”)。

    如果您不太关心项目一旦过期就会从队列中删除,您可以覆盖标准队列的 poll 方法,以检查头部的过期,如果它已过期,清空队列,返回null。

    【讨论】:

      【解决方案2】:

      如果你想删除过期对象,你需要一个 DelayQueue 和一个 Thread 来从中提取过期对象,如下所示:

      static class Wrapper<E> implements Delayed {
          E target;
          long exp = System.currentTimeMillis() + 5000; // 5000 ms delay
      
          Wrapper(E target) {
              this.target = target;
          }
      
          E get() {
              return target;
          }
      
          @Override
          public int compareTo(Delayed o) {
              return 0;
          }
      
          @Override
          public long getDelay(TimeUnit unit) {
              return unit.convert(exp - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
          }
      }
      
      
      public static void main(String[] args) throws Exception {
          final DelayQueue<Wrapper<Integer>> q = new DelayQueue<>();
          q.add(new Wrapper<>(1));
          Thread.sleep(3000);
          q.add(new Wrapper<>(2));
      
          new Thread() {
              public void run() {
                  try {
                      for(;;) {
                          Wrapper<Integer> w = q.take();
                          System.out.println(w.get());
                      }
                  } catch (InterruptedException e) {
                      throw new RuntimeException(e);
                  }
              };
          }.start();
      }
      

      【讨论】:

      • 如果我向队列中添加更多元素,这将无法正常工作。 q.add(new Wrapper(1));线程.sleep(1000); q.add(new Wrapper(2));线程.sleep(1000); q.add(new Wrapper(1));线程.sleep(1000); q.add(new Wrapper(2));
      【解决方案3】:

      我猜这不是 java 中的原生实现,我不确定。但是你可以缓存来保存这种情况,不确定是否是最好的方法,但你可以使用 google guava,为你的 itens 设置一个过期时间,这样你就只会恢复未过期的值。

      这里是 google guava 缓存实现的文档:Guava Doc

      希望对你有帮助!

      【讨论】:

        猜你喜欢
        • 2018-06-18
        • 2011-12-28
        • 2016-11-11
        • 1970-01-01
        • 2016-11-08
        • 1970-01-01
        • 1970-01-01
        • 2016-06-28
        • 1970-01-01
        相关资源
        最近更新 更多