Guava缓存及Guava线程池
最佳答案 问答题库668位专家为你答疑解惑
Guava缓存
Guava缓存是Google Guava库中提供的一种缓存实现,可以帮助我们在应用程序中轻松实现缓存功能。Guava缓存提供了一些高级功能,例如自动加载、过期时间、最大缓存大小、缓存回收等。
CacheBuilder跟Guava缓存的关系
CacheBuilder是Guava缓存的构建器,提供了一些方法来配置缓存的行为,例如设置缓存的最大大小、过期时间、缓存回收策略等。通过CacheBuilder,可以创建一个Guava缓存实例。
即CacheBuilder是Guava缓存的一部分,提供了一种方便的方式来创建和配置Guava缓存实例。
CacheBuilder类的常用方法
maximumSize(int size)
作用:设置缓存的最大容量,当超过这个容量的时候,最近最少使用的条目会被回收。
Cache<String, String> cache = CacheBuilder.newBuilder().maximumSize(100).build();
maximumWeight(long weight)
作用:设置缓存的最大重量,当超过这个重量的时候,最近最少使用的条目会被回收。
Cache<String, String> cache = CacheBuilder.newBuilder().maximumWeight(1000).build();
expireAfterAccess(long duration, TimeUnit unit)
作用:在指定时间内没有被读/写访问,则回收缓存条目。
Cache<String, String> cache = CacheBuilder.newBuilder().expireAfterAccess(10, TimeUnit.MINUTES).build();
expireAfterWrite(long duration, TimeUnit unit)
作用:在指定时间内没有被写访问,则回收缓存条目。
Cache<String, String> cache = CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES).build();
refreshAfterWrite(long duration, TimeUnit unit)
作用:设置缓存项在写入一定时间后自动刷新。
Cache<String, String> cache = CacheBuilder.newBuilder().refreshAfterWrite(10, TimeUnit.MINUTES).build();
initialCapacity(int capacity)
作用:设置缓存的初始容量,用于控制缓存的内存分配。
Cache<String, String> cache = CacheBuilder.newBuilder().initialCapacity(100).build();
recordStats()
作用:启用缓存统计信息,可以获取缓存的命中率、平均加载时间等指标。
Cache<String, String> cache = CacheBuilder.newBuilder().recordStats().build();
build()
作用:构建缓存实例。
Cache<String, String> cache = CacheBuilder.newBuilder().maximumSize(100).build();
build方法用于构建一个缓存对象。接受一个CacheLoader对象作为参数,用于定义缓存的加载逻辑。CacheLoader是一个抽象类,需要实现load方法来定义如何加载缓存数据。
build方法定义:
public <K, V> Cache<K, V> build(CacheLoader<? super K, V> loader)
该方法返回一个Cache对象,该对象可以用于存储和获取缓存数据
示例代码:
public void test() {// 创建一个Cache对象Cache<String, String> cache = CacheBuilder.newBuilder().maximumSize(100) // 设置缓存的最大容量.expireAfterWrite(10, TimeUnit.MINUTES) // 设置缓存项的过期时间.build(new CacheLoader<String, String>() {@Overridepublic String load(String key) throws Exception {// 在缓存中没有找到对应值时,自动加载该值return "value for " + key;}});try {// 获取缓存数据String value = cache.get("key");System.out.println(value); // 输出:Value for key// 缓存中不存在该数据时,会调用CacheLoader的load方法加载数据String value2 = cache.get("key2");System.out.println(value2); // 输出:Value for key2} catch (ExecutionException e) {e.printStackTrace();}}
创建了一个最大容量为100,写入后10分钟过期的缓存实例,并使用CacheLoader自动加载缓存值。当缓存中没有找到对应值时,CacheLoader的load方法会被调用,返回对应的值。
CacheLoader类
CacheLoader类是Guava缓存库中的一个重要类,用于定义缓存加载的逻辑。
CacheLoader类的常用方法
load(K key)
作用:加载指定键的缓存值。如果缓存中不存在该键的值,则通过该方法加载并返回
- 当缓存中不存在指定键的值时,会调用该方法。
- 该方法用于从数据源或其他方式获取缓存的值。
loadAll(Iterable<? extends K> keys)
作用:批量加载指定键集合的缓存值。如果缓存中不存在某个键的值,则通过该方法加载
acheLoader<String, String> cacheLoader = new CacheLoader<String, String>() {@Overridepublic Map<String, String> loadAll(Iterable<? extends String> keys) throws Exception {Map<String, String> values = new HashMap<>();for (String key : keys) {// 从数据库或其他数据源加载缓存值的逻辑values.put(key, "Value for " + key);}return values;}
};List<String> keys = Arrays.asList("key1", "key2", "key3");
Map<String, String> values = cacheLoader.loadAll(keys);
System.out.println(values); // Output: {key1=Value for key1, key2=Value for key2, key3=Value for key3}
reload(K key, V oldValue)
作用:重新加载指定键的缓存值。该方法在缓存值过期或被移除时调用,用于更新缓存值
- 当缓存中的键值对需要被刷新或重新加载时,会调用该方法。
- 该方法在缓存中存在旧值的情况下被调用,用于获取新值并替换旧值。
- 通常在缓存的刷新策略中使用,例如定时刷新或手动刷新。
import com.google.common.cache.CacheLoader;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;import java.util.concurrent.Executor;
import java.util.concurrent.Executors;public class MyCacheLoader<K, V> extends CacheLoader<K, V> {private Executor executor = Executors.newSingleThreadExecutor();@Overridepublic V load(K key) throws Exception {// 在这里实现加载缓存的逻辑// 返回缓存值return null;}@Overridepublic ListenableFuture<V> reload(K key, V oldValue) throws Exception {SettableFuture<V> future = SettableFuture.create();executor.execute(() -> {try {// 在这里实现重新加载缓存的逻辑// 将重新加载的缓存值设置到future中V newValue = null;future.set(newValue);} catch (Exception e) {// 如果重新加载缓存失败,设置异常到future中future.setException(e);}});return future;}
}
创建了一个自定义的CacheLoader类,继承自CacheLoader<K, V>。在load方法中,你可以实现加载缓存的逻辑,并返回缓存值。
在reload方法中,使用了ListenableFuture来表示重新加载缓存的异步操作。创建了一个SettableFuture对象,用于保存重新加载的缓存值。然后,使用一个Executor来执行重新加载缓存的逻辑,将重新加载的缓存值设置到future中。如果重新加载缓存失败,我们将异常设置到future中。
这样,就可以在CacheLoader类中使用reload方法来实现缓存的重新加载操作了。
Guava线程池
Guava的线程池主要包含以下几个类:
-
ListeningExecutorService:一个可监听的ExecutorService,可以在任务执行完成时触发回调函数。
-
MoreExecutors:提供了一些常用的ExecutorService的工厂方法,例如newDirectExecutorService()、newFixedThreadPool()、newCachedThreadPool()等。
-
ThreadFactoryBuilder:一个用于创建线程工厂的Builder类,可以设置线程名、优先级、是否为守护线程等属性。
import com.google.common.util.concurrent.*;import java.util.concurrent.Callable;
import java.util.concurrent.Executors;public class GuavaThreadPoolDemo {public static void main(String[] args) throws Exception {// 创建线程池ListeningExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10, new ThreadFactoryBuilder().setNameFormat("guava-pool-%d").setDaemon(true).build()));// 提交任务ListenableFuture<String> future = executorService.submit(new Callable<String>() {@Overridepublic String call() throws Exception {// 模拟耗时操作Thread.sleep(1000);return "Hello, Guava!";}});// 添加回调函数Futures.addCallback(future, new FutureCallback<String>() {@Overridepublic void onSuccess(String result) {System.out.println(result);}@Overridepublic void onFailure(Throwable t) {t.printStackTrace();}}, executorService);// 关闭线程池executorService.shutdown();}
}
使用MoreExecutors工厂方法创建了一个固定大小的线程池,然后使用ListeningExecutorService包装它,使其可以监听任务执行完成事件。接着,提交了一个Callable任务,并使用Futures.addCallback方法添加了一个回调函数,当任务执行完成时会自动触发回调函数。最后,关闭了线程池。
Guava的线程池和Guava缓存的结合示例代码
import com.google.common.cache.CacheLoader;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;import java.util.concurrent.Executor;
import java.util.concurrent.Executors;public class MyCacheLoader<K, V> extends CacheLoader<K, V> {// 创建线程池ListeningExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10, new ThreadFactoryBuilder().setNameFormat("guava-pool-%d").setDaemon(true).build()));@Overridepublic V load(K key) throws Exception {// 在这里实现加载缓存的逻辑// 返回缓存值return null;}@Overridepublic ListenableFuture<V> reload(K key, V oldValue) throws Exception {SettableFuture<V> future = SettableFuture.create();executorService.execute(() -> {try {// 在这里实现重新加载缓存的逻辑// 将重新加载的缓存值设置到future中V newValue = null;future.set(newValue);} catch (Exception e) {// 如果重新加载缓存失败,设置异常到future中future.setException(e);}});return future;}
}
99%的人还看了
相似问题
猜你感兴趣
版权申明
本文"Guava缓存及Guava线程池":http://eshow365.cn/6-10092-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!
- 上一篇: C++之智能指针shared_ptr死锁问题(二百)
- 下一篇: 【23种设计模式】组合模式(八)