Class CacheBuilder<K,V>
- java.lang.Object
-
- com.google.common.cache.CacheBuilder<K,V>
-
- Type Parameters:
K
- the most general key type this builder will be able to create caches for. This is normallyObject
unless it is constrained by using a method like#removalListener
. Cache keys may not be null.V
- the most general value type this builder will be able to create caches for. This is normallyObject
unless it is constrained by using a method like#removalListener
. Cache values may not be null.
@GwtCompatible(emulated=true) public final class CacheBuilder<K,V> extends java.lang.Object
A builder ofLoadingCache
andCache
instances.Prefer Caffeine over Guava's caching API
The successor to Guava's caching API is Caffeine. Its API is designed to make it a nearly drop-in replacement -- though it requires Java 8 APIs, is not available for Android or GWT/j2cl, and may have different (usually better) behavior when multiple threads attempt concurrent mutations. Its equivalent to
CacheBuilder
is itsCaffeine
class. Caffeine offers better performance, more features (including asynchronous loading), and fewer bugs.Caffeine defines its own interfaces (
Cache
,LoadingCache
,CacheLoader
, etc.), so you can use Caffeine without needing to use any Guava types. Caffeine's types are better than Guava's, especially for their deep support for asynchronous operations. But if you want to migrate to Caffeine with minimal code changes, you can use itsCaffeinatedGuava
adapter class, which lets you build a GuavaCache
or a GuavaLoadingCache
backed by a GuavaCacheLoader
.Caffeine's API for asynchronous operations uses
CompletableFuture
:AsyncLoadingCache.get
returns aCompletableFuture
, and implementations ofAsyncCacheLoader.asyncLoad
must return aCompletableFuture
. Users of Guava'sListenableFuture
can adapt between the twoFuture
types by usingnet.javacrumbs.futureconverter.java8guava.FutureConverter
.More on
CacheBuilder
CacheBuilder
builds caches with any combination of the following features:- automatic loading of entries into the cache
- least-recently-used eviction when a maximum size is exceeded (note that the cache is divided into segments, each of which does LRU internally)
- time-based expiration of entries, measured since last access or last write
- keys automatically wrapped in
WeakReference
- values automatically wrapped in
WeakReference
orSoftReference
- notification of evicted (or otherwise removed) entries
- accumulation of cache access statistics
These features are all optional; caches can be created using all or none of them. By default, cache instances created by
CacheBuilder
will not perform any type of eviction.Usage example:
LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder() .maximumSize(10000) .expireAfterWrite(10, TimeUnit.MINUTES) .removalListener(MY_LISTENER) .build( new CacheLoader<Key, Graph>() { public Graph load(Key key) throws AnyException { return createExpensiveGraph(key); } });
Or equivalently,
// In real life this would come from a command-line flag or config file String spec = "maximumSize=10000,expireAfterWrite=10m"; LoadingCache<Key, Graph> graphs = CacheBuilder.from(spec) .removalListener(MY_LISTENER) .build( new CacheLoader<Key, Graph>() { public Graph load(Key key) throws AnyException { return createExpensiveGraph(key); } });
The returned cache implements all optional operations of the
LoadingCache
andCache
interfaces. TheasMap
view (and its collection views) have weakly consistent iterators. This means that they are safe for concurrent use, but if other threads modify the cache after the iterator is created, it is undefined which of these changes, if any, are reflected in that iterator. These iterators never throwConcurrentModificationException
.Note: by default, the returned cache uses equality comparisons (the
equals
method) to determine equality for keys or values. However, ifweakKeys()
was specified, the cache uses identity (==
) comparisons instead for keys. Likewise, ifweakValues()
orsoftValues()
was specified, the cache uses identity comparisons for values.Entries are automatically evicted from the cache when any of
maximumSize
,maximumWeight
,expireAfterWrite
,expireAfterAccess
,weakKeys
,weakValues
, orsoftValues
are requested.If
maximumSize
ormaximumWeight
is requested entries may be evicted on each cache modification.If
expireAfterWrite
orexpireAfterAccess
is requested entries may be evicted on each cache modification, on occasional cache accesses, or on calls toCache.cleanUp()
. Expired entries may be counted byCache.size()
, but will never be visible to read or write operations.If
weakKeys
,weakValues
, orsoftValues
are requested, it is possible for a key or value present in the cache to be reclaimed by the garbage collector. Entries with reclaimed keys or values may be removed from the cache on each cache modification, on occasional cache accesses, or on calls toCache.cleanUp()
; such entries may be counted inCache.size()
, but will never be visible to read or write operations.Certain cache configurations will result in the accrual of periodic maintenance tasks which will be performed during write operations, or during occasional read operations in the absence of writes. The
Cache.cleanUp()
method of the returned cache will also perform maintenance, but calling it should not be necessary with a high throughput cache. Only caches built withremovalListener
,expireAfterWrite
,expireAfterAccess
,weakKeys
,weakValues
, orsoftValues
perform periodic maintenance.The caches produced by
CacheBuilder
are serializable, and the deserialized caches retain all the configuration properties of the original cache. Note that the serialized form does not include cache contents, but only configuration.See the Guava User Guide article on caching for a higher-level explanation.
- Since:
- 10.0
- Author:
- Charles Fry, Kevin Bourrillion
-
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description <K1 extends K,V1 extends V>
Cache<K1,V1>build()
Builds a cache which does not automatically load values when keys are requested.<K1 extends K,V1 extends V>
LoadingCache<K1,V1>build(CacheLoader<? super K1,V1> loader)
Builds a cache, which either returns an already-loaded value for a given key or atomically computes or retrieves it using the suppliedCacheLoader
.CacheBuilder<K,V>
concurrencyLevel(int concurrencyLevel)
Guides the allowed concurrency among update operations.CacheBuilder<K,V>
expireAfterAccess(long duration, java.util.concurrent.TimeUnit unit)
Specifies that each entry should be automatically removed from the cache once a fixed duration has elapsed after the entry's creation, the most recent replacement of its value, or its last access.CacheBuilder<K,V>
expireAfterWrite(long duration, java.util.concurrent.TimeUnit unit)
Specifies that each entry should be automatically removed from the cache once a fixed duration has elapsed after the entry's creation, or the most recent replacement of its value.static CacheBuilder<java.lang.Object,java.lang.Object>
from(CacheBuilderSpec spec)
Constructs a newCacheBuilder
instance with the settings specified inspec
.static CacheBuilder<java.lang.Object,java.lang.Object>
from(java.lang.String spec)
Constructs a newCacheBuilder
instance with the settings specified inspec
.CacheBuilder<K,V>
initialCapacity(int initialCapacity)
Sets the minimum total size for the internal hash tables.CacheBuilder<K,V>
maximumSize(long maximumSize)
Specifies the maximum number of entries the cache may contain.CacheBuilder<K,V>
maximumWeight(long maximumWeight)
Specifies the maximum weight of entries the cache may contain.static CacheBuilder<java.lang.Object,java.lang.Object>
newBuilder()
Constructs a newCacheBuilder
instance with default settings, including strong keys, strong values, and no automatic eviction of any kind.CacheBuilder<K,V>
recordStats()
Enable the accumulation ofCacheStats
during the operation of the cache.CacheBuilder<K,V>
refreshAfterWrite(long duration, java.util.concurrent.TimeUnit unit)
Specifies that active entries are eligible for automatic refresh once a fixed duration has elapsed after the entry's creation, or the most recent replacement of its value.<K1 extends K,V1 extends V>
CacheBuilder<K1,V1>removalListener(RemovalListener<? super K1,? super V1> listener)
Specifies a listener instance that caches should notify each time an entry is removed for any reason.CacheBuilder<K,V>
softValues()
Specifies that each value (not key) stored in the cache should be wrapped in aSoftReference
(by default, strong references are used).CacheBuilder<K,V>
ticker(Ticker ticker)
Specifies a nanosecond-precision time source for this cache.java.lang.String
toString()
Returns a string representation for this CacheBuilder instance.CacheBuilder<K,V>
weakKeys()
Specifies that each key (not value) stored in the cache should be wrapped in aWeakReference
(by default, strong references are used).CacheBuilder<K,V>
weakValues()
Specifies that each value (not key) stored in the cache should be wrapped in aWeakReference
(by default, strong references are used).<K1 extends K,V1 extends V>
CacheBuilder<K1,V1>weigher(Weigher<? super K1,? super V1> weigher)
Specifies the weigher to use in determining the weight of entries.
-
-
-
Method Detail
-
newBuilder
public static CacheBuilder<java.lang.Object,java.lang.Object> newBuilder()
Constructs a newCacheBuilder
instance with default settings, including strong keys, strong values, and no automatic eviction of any kind.Note that while this return type is
CacheBuilder<Object, Object>
, type parameters on thebuild(com.google.common.cache.CacheLoader<? super K1, V1>)
methods allow you to create a cache of any key and value type desired.
-
from
@GwtIncompatible public static CacheBuilder<java.lang.Object,java.lang.Object> from(CacheBuilderSpec spec)
Constructs a newCacheBuilder
instance with the settings specified inspec
.- Since:
- 12.0
-
from
@GwtIncompatible public static CacheBuilder<java.lang.Object,java.lang.Object> from(java.lang.String spec)
Constructs a newCacheBuilder
instance with the settings specified inspec
. This is especially useful for command-line configuration of aCacheBuilder
.- Parameters:
spec
- a String in the format specified byCacheBuilderSpec
- Since:
- 12.0
-
initialCapacity
@CanIgnoreReturnValue public CacheBuilder<K,V> initialCapacity(int initialCapacity)
Sets the minimum total size for the internal hash tables. For example, if the initial capacity is60
, and the concurrency level is8
, then eight segments are created, each having a hash table of size eight. Providing a large enough estimate at construction time avoids the need for expensive resizing operations later, but setting this value unnecessarily high wastes memory.- Returns:
- this
CacheBuilder
instance (for chaining) - Throws:
java.lang.IllegalArgumentException
- ifinitialCapacity
is negativejava.lang.IllegalStateException
- if an initial capacity was already set
-
concurrencyLevel
@CanIgnoreReturnValue public CacheBuilder<K,V> concurrencyLevel(int concurrencyLevel)
Guides the allowed concurrency among update operations. Used as a hint for internal sizing. The table is internally partitioned to try to permit the indicated number of concurrent updates without contention. Because assignment of entries to these partitions is not necessarily uniform, the actual concurrency observed may vary. Ideally, you should choose a value to accommodate as many threads as will ever concurrently modify the table. Using a significantly higher value than you need can waste space and time, and a significantly lower value can lead to thread contention. But overestimates and underestimates within an order of magnitude do not usually have much noticeable impact. A value of one permits only one thread to modify the cache at a time, but since read operations and cache loading computations can proceed concurrently, this still yields higher concurrency than full synchronization.Defaults to 4. Note:The default may change in the future. If you care about this value, you should always choose it explicitly.
The current implementation uses the concurrency level to create a fixed number of hashtable segments, each governed by its own write lock. The segment lock is taken once for each explicit write, and twice for each cache loading computation (once prior to loading the new value, and once after loading completes). Much internal cache management is performed at the segment granularity. For example, access queues and write queues are kept per segment when they are required by the selected eviction algorithm. As such, when writing unit tests it is not uncommon to specify
concurrencyLevel(1)
in order to achieve more deterministic eviction behavior.Note that future implementations may abandon segment locking in favor of more advanced concurrency controls.
- Returns:
- this
CacheBuilder
instance (for chaining) - Throws:
java.lang.IllegalArgumentException
- ifconcurrencyLevel
is nonpositivejava.lang.IllegalStateException
- if a concurrency level was already set
-
maximumSize
@CanIgnoreReturnValue public CacheBuilder<K,V> maximumSize(long maximumSize)
Specifies the maximum number of entries the cache may contain.Note that the cache may evict an entry before this limit is exceeded. For example, in the current implementation, when
concurrencyLevel
is greater than1
, each resulting segment inside the cache independently limits its own size to approximatelymaximumSize / concurrencyLevel
.When eviction is necessary, the cache evicts entries that are less likely to be used again. For example, the cache may evict an entry because it hasn't been used recently or very often.
If
maximumSize
is zero, elements will be evicted immediately after being loaded into cache. This can be useful in testing, or to disable caching temporarily.This feature cannot be used in conjunction with
maximumWeight
.- Parameters:
maximumSize
- the maximum size of the cache- Returns:
- this
CacheBuilder
instance (for chaining) - Throws:
java.lang.IllegalArgumentException
- ifmaximumSize
is negativejava.lang.IllegalStateException
- if a maximum size or weight was already set
-
maximumWeight
@GwtIncompatible @CanIgnoreReturnValue public CacheBuilder<K,V> maximumWeight(long maximumWeight)
Specifies the maximum weight of entries the cache may contain. Weight is determined using theWeigher
specified withweigher
, and use of this method requires a corresponding call toweigher
prior to callingbuild(com.google.common.cache.CacheLoader<? super K1, V1>)
.Note that the cache may evict an entry before this limit is exceeded. For example, in the current implementation, when
concurrencyLevel
is greater than1
, each resulting segment inside the cache independently limits its own weight to approximatelymaximumWeight / concurrencyLevel
.When eviction is necessary, the cache evicts entries that are less likely to be used again. For example, the cache may evict an entry because it hasn't been used recently or very often.
If
maximumWeight
is zero, elements will be evicted immediately after being loaded into cache. This can be useful in testing, or to disable caching temporarily.Note that weight is only used to determine whether the cache is over capacity; it has no effect on selecting which entry should be evicted next.
This feature cannot be used in conjunction with
maximumSize
.- Parameters:
maximumWeight
- the maximum total weight of entries the cache may contain- Returns:
- this
CacheBuilder
instance (for chaining) - Throws:
java.lang.IllegalArgumentException
- ifmaximumWeight
is negativejava.lang.IllegalStateException
- if a maximum weight or size was already set- Since:
- 11.0
-
weigher
@GwtIncompatible @CanIgnoreReturnValue public <K1 extends K,V1 extends V> CacheBuilder<K1,V1> weigher(Weigher<? super K1,? super V1> weigher)
Specifies the weigher to use in determining the weight of entries. Entry weight is taken into consideration bymaximumWeight(long)
when determining which entries to evict, and use of this method requires a corresponding call tomaximumWeight(long)
prior to callingbuild(com.google.common.cache.CacheLoader<? super K1, V1>)
. Weights are measured and recorded when entries are inserted into the cache, and are thus effectively static during the lifetime of a cache entry.When the weight of an entry is zero it will not be considered for size-based eviction (though it still may be evicted by other means).
Important note: Instead of returning this as a
CacheBuilder
instance, this method returnsCacheBuilder<K1, V1>
. From this point on, either the original reference or the returned reference may be used to complete configuration and build the cache, but only the "generic" one is type-safe. That is, it will properly prevent you from building caches whose key or value types are incompatible with the types accepted by the weigher already provided; theCacheBuilder
type cannot do this. For best results, simply use the standard method-chaining idiom, as illustrated in the documentation at top, configuring aCacheBuilder
and building yourCache
all in a single statement.Warning: if you ignore the above advice, and use this
CacheBuilder
to build a cache whose key or value type is incompatible with the weigher, you will likely experience aClassCastException
at some undefined point in the future.- Parameters:
weigher
- the weigher to use in calculating the weight of cache entries- Returns:
- this
CacheBuilder
instance (for chaining) - Throws:
java.lang.IllegalArgumentException
- ifsize
is negativejava.lang.IllegalStateException
- if a maximum size was already set- Since:
- 11.0
-
weakKeys
@GwtIncompatible @CanIgnoreReturnValue public CacheBuilder<K,V> weakKeys()
Specifies that each key (not value) stored in the cache should be wrapped in aWeakReference
(by default, strong references are used).Warning: when this method is used, the resulting cache will use identity (
==
) comparison to determine equality of keys. ItsCache.asMap()
view will therefore technically violate theMap
specification (in the same way thatIdentityHashMap
does).Entries with keys that have been garbage collected may be counted in
Cache.size()
, but will never be visible to read or write operations; such entries are cleaned up as part of the routine maintenance described in the class javadoc.- Returns:
- this
CacheBuilder
instance (for chaining) - Throws:
java.lang.IllegalStateException
- if the key strength was already set
-
weakValues
@GwtIncompatible @CanIgnoreReturnValue public CacheBuilder<K,V> weakValues()
Specifies that each value (not key) stored in the cache should be wrapped in aWeakReference
(by default, strong references are used).Weak values will be garbage collected once they are weakly reachable. This makes them a poor candidate for caching; consider
softValues()
instead.Note: when this method is used, the resulting cache will use identity (
==
) comparison to determine equality of values.Entries with values that have been garbage collected may be counted in
Cache.size()
, but will never be visible to read or write operations; such entries are cleaned up as part of the routine maintenance described in the class javadoc.- Returns:
- this
CacheBuilder
instance (for chaining) - Throws:
java.lang.IllegalStateException
- if the value strength was already set
-
softValues
@GwtIncompatible @CanIgnoreReturnValue public CacheBuilder<K,V> softValues()
Specifies that each value (not key) stored in the cache should be wrapped in aSoftReference
(by default, strong references are used). Softly-referenced objects will be garbage-collected in a globally least-recently-used manner, in response to memory demand.Warning: in most circumstances it is better to set a per-cache maximum size instead of using soft references. You should only use this method if you are well familiar with the practical consequences of soft references.
Note: when this method is used, the resulting cache will use identity (
==
) comparison to determine equality of values.Entries with values that have been garbage collected may be counted in
Cache.size()
, but will never be visible to read or write operations; such entries are cleaned up as part of the routine maintenance described in the class javadoc.- Returns:
- this
CacheBuilder
instance (for chaining) - Throws:
java.lang.IllegalStateException
- if the value strength was already set
-
expireAfterWrite
@CanIgnoreReturnValue public CacheBuilder<K,V> expireAfterWrite(long duration, java.util.concurrent.TimeUnit unit)
Specifies that each entry should be automatically removed from the cache once a fixed duration has elapsed after the entry's creation, or the most recent replacement of its value.When
duration
is zero, this method hands off tomaximumSize
(0)
, ignoring any otherwise-specified maximum size or weight. This can be useful in testing, or to disable caching temporarily without a code change.Expired entries may be counted in
Cache.size()
, but will never be visible to read or write operations. Expired entries are cleaned up as part of the routine maintenance described in the class javadoc.- Parameters:
duration
- the length of time after an entry is created that it should be automatically removedunit
- the unit thatduration
is expressed in- Returns:
- this
CacheBuilder
instance (for chaining) - Throws:
java.lang.IllegalArgumentException
- ifduration
is negativejava.lang.IllegalStateException
- ifexpireAfterWrite(long, java.util.concurrent.TimeUnit)
was already set
-
expireAfterAccess
@CanIgnoreReturnValue public CacheBuilder<K,V> expireAfterAccess(long duration, java.util.concurrent.TimeUnit unit)
Specifies that each entry should be automatically removed from the cache once a fixed duration has elapsed after the entry's creation, the most recent replacement of its value, or its last access. Access time is reset by all cache read and write operations (includingCache.asMap().get(Object)
andCache.asMap().put(K, V)
), but not bycontainsKey(Object)
, nor by operations on the collection-views ofCache.asMap()
. So, for example, iterating throughCache.asMap().entrySet()
does not reset access time for the entries you retrieve.When
duration
is zero, this method hands off tomaximumSize
(0)
, ignoring any otherwise-specified maximum size or weight. This can be useful in testing, or to disable caching temporarily without a code change.Expired entries may be counted in
Cache.size()
, but will never be visible to read or write operations. Expired entries are cleaned up as part of the routine maintenance described in the class javadoc.- Parameters:
duration
- the length of time after an entry is last accessed that it should be automatically removedunit
- the unit thatduration
is expressed in- Returns:
- this
CacheBuilder
instance (for chaining) - Throws:
java.lang.IllegalArgumentException
- ifduration
is negativejava.lang.IllegalStateException
- ifexpireAfterAccess(long, java.util.concurrent.TimeUnit)
was already set
-
refreshAfterWrite
@GwtIncompatible @CanIgnoreReturnValue public CacheBuilder<K,V> refreshAfterWrite(long duration, java.util.concurrent.TimeUnit unit)
Specifies that active entries are eligible for automatic refresh once a fixed duration has elapsed after the entry's creation, or the most recent replacement of its value. The semantics of refreshes are specified inLoadingCache.refresh(K)
, and are performed by callingCacheLoader.reload(K, V)
.As the default implementation of
CacheLoader.reload(K, V)
is synchronous, it is recommended that users of this method overrideCacheLoader.reload(K, V)
with an asynchronous implementation; otherwise refreshes will be performed during unrelated cache read and write operations.Currently automatic refreshes are performed when the first stale request for an entry occurs. The request triggering refresh will make a synchronous call to
CacheLoader.reload(K, V)
and immediately return the new value if the returned future is complete, and the old value otherwise.Note: all exceptions thrown during refresh will be logged and then swallowed.
- Parameters:
duration
- the length of time after an entry is created that it should be considered stale, and thus eligible for refreshunit
- the unit thatduration
is expressed in- Returns:
- this
CacheBuilder
instance (for chaining) - Throws:
java.lang.IllegalArgumentException
- ifduration
is negativejava.lang.IllegalStateException
- ifrefreshAfterWrite(long, java.util.concurrent.TimeUnit)
was already set- Since:
- 11.0
-
ticker
@CanIgnoreReturnValue public CacheBuilder<K,V> ticker(Ticker ticker)
Specifies a nanosecond-precision time source for this cache. By default,System.nanoTime()
is used.The primary intent of this method is to facilitate testing of caches with a fake or mock time source.
- Returns:
- this
CacheBuilder
instance (for chaining) - Throws:
java.lang.IllegalStateException
- if a ticker was already set
-
removalListener
public <K1 extends K,V1 extends V> CacheBuilder<K1,V1> removalListener(RemovalListener<? super K1,? super V1> listener)
Specifies a listener instance that caches should notify each time an entry is removed for any reason. Each cache created by this builder will invoke this listener as part of the routine maintenance described in the class documentation above.Warning: after invoking this method, do not continue to use this cache builder reference; instead use the reference this method returns. At runtime, these point to the same instance, but only the returned reference has the correct generic type information to ensure type safety. For best results, use the standard method-chaining idiom illustrated in the class documentation above, configuring a builder and building your cache in a single statement. Failure to heed this advice can result in a
ClassCastException
being thrown by a cache operation at some undefined point in the future.Warning: any exception thrown by
listener
will not be propagated to theCache
user, only logged via aLogger
.- Returns:
- the cache builder reference that should be used instead of
this
for any remaining configuration and cache building - Throws:
java.lang.IllegalStateException
- if a removal listener was already set
-
recordStats
@CanIgnoreReturnValue public CacheBuilder<K,V> recordStats()
Enable the accumulation ofCacheStats
during the operation of the cache. Without thisCache.stats()
will return zero for all statistics. Note that recording stats requires bookkeeping to be performed with each operation, and thus imposes a performance penalty on cache operation.- Returns:
- this
CacheBuilder
instance (for chaining) - Since:
- 12.0 (previously, stats collection was automatic)
-
build
public <K1 extends K,V1 extends V> LoadingCache<K1,V1> build(CacheLoader<? super K1,V1> loader)
Builds a cache, which either returns an already-loaded value for a given key or atomically computes or retrieves it using the suppliedCacheLoader
. If another thread is currently loading the value for this key, simply waits for that thread to finish and returns its loaded value. Note that multiple threads can concurrently load values for distinct keys.This method does not alter the state of this
CacheBuilder
instance, so it can be invoked again to create multiple independent caches.- Parameters:
loader
- the cache loader used to obtain new values- Returns:
- a cache having the requested features
-
build
public <K1 extends K,V1 extends V> Cache<K1,V1> build()
Builds a cache which does not automatically load values when keys are requested.Consider
build(CacheLoader)
instead, if it is feasible to implement aCacheLoader
.This method does not alter the state of this
CacheBuilder
instance, so it can be invoked again to create multiple independent caches.- Returns:
- a cache having the requested features
- Since:
- 11.0
-
toString
public java.lang.String toString()
Returns a string representation for this CacheBuilder instance. The exact form of the returned string is not specified.- Overrides:
toString
in classjava.lang.Object
-
-