2015-04-01 72 views
2

我需要一個隊列,它會自動刪除超過給定的毫秒數的元素 - 基本上,我希望隊列中的項目在一段時間後過期。DelayQueue有沒有相反的地方?

我看到有一個延遲隊列,看起來正在做相反的事情:'一個元素只能在其延遲期滿時才被採用。' (我從來沒有用過)。

也許有一個隊列實現,做我所需要的?如果它有界,情況會更好。

回答

1

如果要刪除過期的對象,你需要一個DelayQueue和線程將從其中提取過期的對象,這樣的事情:

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(); 
} 
0

我猜不是像java那樣的原生實現,我不確定通過。但是你可以緩存來保存這種情況,不確定是否是最好的approuch,但是你可以使用google guava,爲你的itens設置一個Expiration Time,這樣你只能恢復沒有過期的值。

下面是谷歌的番石榴緩存實現文檔:Guava Doc

希望它能幫助!

1

的問題,這是在該點將刪除已過期的元素。如果你關心的是隊列的大小沒有超過一定的限制,你將不得不有一個單獨的「更乾淨的」線程,在隊列過期時將其從隊列中移除。您可以使用DelayQueueoffer將添加到內部LinkedHashSetDelayQueue,poll對該集合進行操作,並且此外更乾淨的線程輪詢DelayQueue,並在「成熟」時從集合中刪除事物)來實現它。

如果您不關心一旦到期的項目將從隊列中刪除,那麼您可以覆蓋標準隊列的poll方法,以檢查頭部到期,並且如果它已過期,清除隊列的其餘部分並返回null。

相關問題