Skip to content
Ben Manes edited this page Aug 18, 2017 · 11 revisions

Pinning Entries

A pinned entry is one that cannot be removed by an eviction policy. This is useful when the entry is a stateful resource, like a lock, that can only be discarded after the client has finished using it. In those cases the behavior of evicting an entry and recomputing it would cause a resource leak.

An entry can be excluded from maximum size eviction by using weights and evaluating the entry to a weight of zero. The entry then does not count towards the overall capacity and is skipped by the maximum size eviction. A custom Weigher must be defined that can evaluate if the entry is pinned.

An entry can be excluded from expiration by using a duration of Long.MAX_VALUE, or roughly 300 years. A custom Expiry must be defined that can evaluate if the entry is pinned.

The weight and expiration are evaluated when the entry is written into the cache. This can be accomplished using cache.asMap().compute to pin and unpin the entry.

Recursive Computations

A load, computation, or callbacks performed inside of an atomic operation may not write into the cache. These recursive writes are not allowed by ConcurrentHashMap and may result in a livelock (Java 8) or an IllegalStateException (Java 9).

A workaround is to perform the computation asynchronously, such as by using AsyncLoadingCache. In this scenario the mapping has been established, the value is a CompletableFuture, and the computation is performed outside of the cache's atomic scope. This may still deadlock if an unordered dependency chain occurs.

Clone this wiki locally