2016-05-31 6 views
0

は、私はこのような何かをしたい:weakValues()とexpireAfterAccess()を組み合わせることはできますか?

CacheBuilder 
      .newBuilder() 
      .maximumSize(CONFIG.cacheMaxSize()) 
      .expireAfterAccess(CONFIG.cacheTimeout(), 
           CONFIG.cacheTimeUnit()) 
      .weakValues() 
      .build(cacheLoader); 

私は期待して動作が値が参照されていない場合、エントリにのみ期限切れとなり、有効期限が経過したことです。この使用法はどのように機能するのでしょうか?

答えて

2

ないが、弱い値がゴミを収集することができますので、オブジェクトへの強い参照がなくなると直ちに終了します。ただし、弱い値のキャッシュと時間切れのキャッシュの2つのキャッシュによってバックアップされたForwardingCacheを使用すると、時間ベースのキャッシュはオブジェクトへの強い参照を保持し、弱い値のキャッシュに保持されます。関連する積載方法にweakCacheexpiringCache.put()それから値をロードする必要がありますあなたはあなた以上.get()のように、同様ForwardingLoadingCacheと同じことを行うことができます

public class WeakValuedExpiringCache<K, V> extends ForwardingCache<K, V> { 
    private final Cache<K, V> expiringCache; 
    private final Cache<K, V> weakCache; 

    public WeakValuedExpiringCache(CacheBuilder expiringSpec) { 
    expiringCache = expiringSpec.build(); 
    weakCache = CacheBuilder.newBuilder().weakValues().build(); 
    } 

    // weakCache is the canonical cache since it will hold values longer than 
    // expiration if there remain other strong references 
    protected Cache<K, V> delagate() { 
    return weakCache; 
    } 

    @override 
    public V get(K key, Callable<? extends V> valueLoader) 
    throws ExecutionException { 
    // repopulate the expiring cache if needed, and update the weak cache 
    V value = expiringCache.get(key, valueLoader); 
    weakCache.put(key, value); // don't call super.put() here 
    } 

    @Override 
    public void put(K key, V value) { 
    expiringCache.put(key, value); 
    super.put(key, value); 
    } 

    // Handle putAll(), cleanUp(), invalidate(), and invalidateAll() similarly 
} 

:それはこのような何かを見てね。

+0

ありがとう!それは最高です。そして、あなたは私の質問に、私はキャッシュにBESIDES値への他の参照がなければならないということを知っていました。弱い参照がgcを防ぐことは決してないと私は考えなかった。 – jacob

1

値が参照されていないか、有効期限が経過した場合いいえ、エントリは期限切れになります:

public class CacheBuilderIT { 
    @Test 
    public void expireAfterAccessWithWeakValues() throws InterruptedException { 
     Cache<Object, Object> cache = CacheBuilder.newBuilder() 
       .expireAfterAccess(500, MILLISECONDS) 
       .weakValues() 
       .build(); 
     Object key = new Object(); 
     Object value = new Object(); // keep a strong reference to the value 
     cache.put(key, value); 
     Thread.sleep(300); 
     assert cache.getIfPresent(key) != null : "expiration occurred too quickly"; 
     Thread.sleep(300); 
     assert cache.getIfPresent(key) != null : "last access did not reset expiration"; 
     Thread.sleep(1000); 
     assert cache.getIfPresent(key) != null : "reference did not prevent expiration"; 
    } 
} 

Ouptut:直接

java.lang.AssertionError: reference did not prevent expiration 
+0

ありがとうございました! – jacob

関連する問題