A semi-persistent mapping from keys to values. Values are automatically loaded by the cache, and are stored in the cache until either evicted or manually invalidated.
Implementations of this interface are expected to be thread-safe, and can be safely accessed by multiple concurrent threads.接口描述与Cache相同
- 提供键值对的半永久映射。
- Entry通过get或put缓存到Cache中直到被驱逐或失效。
- 该接口的实现应该是线程安全的,并可以由多个并发线程安全访问。
继承Cache接口,提供同步自动加载数据的接口。
在Cache的接口上扩展了三个接口:
-
get
/** * Returns the value associated with the {@code key} in this cache, obtaining that value from * {@link CacheLoader#load(Object)} if necessary. * <p> * If another call to {@link #get} is currently loading the value for the {@code key}, this thread * simply waits for that thread to finish and returns its loaded value. Note that multiple threads * can concurrently load values for distinct keys. * <p> * If the specified key is not already associated with a value, attempts to compute its value and * enters it into this cache unless {@code null}. The entire method invocation is performed * atomically, so the function is applied at most once per key. Some attempted update operations * on this cache by other threads may be blocked while the computation is in progress, so the * computation should be short and simple, and must not attempt to update any other mappings of * this cache. * * @param key key with which the specified value is to be associated * @return the current (existing or computed) value associated with the specified key, or null if * the computed value is null * @throws NullPointerException if the specified key is null * @throws IllegalStateException if the computation detectably attempts a recursive update to this * cache that would otherwise never complete * @throws CompletionException if a checked exception was thrown while loading the value * @throws RuntimeException or Error if the {@link CacheLoader} does so, in which case the mapping * is left unestablished */ @Nullable V get(@NonNull K key);
- 获取key对应的value,在必要时通过CacheLoader加载数据。
- 加载的非
null
数据会缓存到Cache中。 - 如果同时已有其他线程在加载key对应的数据,当前线程阻塞
waits
,等待那个线程加载并返回那个加载到的数据。
-
getAll
/** * Returns a map of the values associated with the {@code keys}, creating or retrieving those * values if necessary. The returned map contains entries that were already cached, combined with * the newly loaded entries; it will never contain null keys or values. * <p> * Caches loaded by a {@link CacheLoader} will issue a single request to * {@link CacheLoader#loadAll} for all keys which are not already present in the cache. All * entries returned by {@link CacheLoader#loadAll} will be stored in the cache, over-writing any * previously cached values. If another call to {@link #get} tries to load the value for a key in * {@code keys}, implementations may either have that thread load the entry or simply wait for * this thread to finish and returns the loaded value. In the case of overlapping non-blocking * loads, the last load to complete will replace the existing entry. Note that multiple threads * can concurrently load values for distinct keys. * <p> * Note that duplicate elements in {@code keys}, as determined by {@link Object#equals}, will be * ignored. * * @param keys the keys whose associated values are to be returned * @return the unmodifiable mapping of keys to values for the specified keys in this cache * @throws NullPointerException if the specified collection is null or contains a null element * @throws CompletionException if a checked exception was thrown while loading the value * @throws RuntimeException or Error if the {@link CacheLoader} does so, if * {@link CacheLoader#loadAll} returns {@code null}, returns a map containing null keys or * values, or fails to return an entry for each requested key. In all cases, the mapping * is left unestablished */ @NonNull Map<@NonNull K, @NonNull V> getAll(@NonNull Iterable<? extends @NonNull K> keys);
-
获取所有key对应的value,在必要时通过CacheLoader加载数据。
-
加载的非
null
数据会缓存到Cache中。 -
如果同时已有其他线程在加载某个key对应的数据,当前线程阻塞
waits
,等待那个线程加载并返回那个加载到的数据。假设:线程t1加载("key1", "key2", "key3", "key4"),线程t2加载("key1", "key4"),t1先执行,每次执行加载所需时间都为c。
- t1加载key1的时候,t2阻塞等等t1加载完key1;
- t1加载key1后,开始加载key2;此时t2获得key1的值,开始加载key4;
- t2加载完key4后,任务结束;t1加载key4时,key4已经在缓存中,直接从缓存中取数据,结束。
- 最终:t1加载key1、key2、key3,耗时大约3c;t2加载key4,耗时大约2c,其中阻塞等待key1耗时大约为c。
-
-
refresh
/** * Loads a new value for the {@code key}, asynchronously. While the new value is loading the * previous value (if any) will continue to be returned by {@code get(key)} unless it is evicted. * If the new value is loaded successfully it will replace the previous value in the cache; if an * exception is thrown while refreshing the previous value will remain, <i>and the exception will * be logged (using {@link java.util.logging.Logger}) and swallowed</i>. * <p> * Caches loaded by a {@link CacheLoader} will call {@link CacheLoader#reload} if the cache * currently contains a value for the {@code key}, and {@link CacheLoader#load} otherwise. Loading * is asynchronous by delegating to the default executor. * * @param key key with which a value may be associated * @throws NullPointerException if the specified key is null */ void refresh(@NonNull K key);
-
异步刷新key对应的缓存数据
-
在新数据加载成功前,旧数据仍可用(除非过期或被驱逐)
-
新数据加载成功后,replace旧数据
-
如果数据加载时异常,会被swallowed。
-
如果数据加载的value为null,key对应的Entry会从缓存中移除。
-
网友评论