前言

  • LoadingCache是Guava Cache库中的一个类,它继承了Cache接口,并且扩展了它,提供了方便的方法来加载和缓存数据。 具体来说,LoadingCache类提供了一种从缓存中加载数据的机制,如果缓存中没有所需的数据,则会使用提供的加载函数来加载数据,然后将其放入缓存中,以便在将来使用。

这是一个使用Guava Cache的LoadingCache的简单例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;

import java.util.concurrent.TimeUnit;

public class LoadingCacheExample {

// 创建一个LoadingCache对象,并指定缓存大小为100,缓存数据保存1小时
private static final LoadingCache<String, String> CACHE = CacheBuilder.newBuilder()
.maximumSize(100)
.expireAfterWrite(1, TimeUnit.HOURS)
.build(
new CacheLoader<String, String>() {
@Override
public String load(String key) throws Exception {
// 如果缓存中不存在所需数据,则使用下面的方法加载数据
return loadDataFromDatabase(key);
}
});

public static void main(String[] args) {
try {
// 从缓存中获取key为"key1"的数据
String data = CACHE.get("key1");
System.out.println(data);

// 从缓存中获取key为"key2"的数据
data = CACHE.get("key2");
System.out.println(data);
} catch (Exception e) {
e.printStackTrace();
}
}

private static String loadDataFromDatabase(String key) {
// 这里只是简单地模拟从数据库加载数据
return key + ":data";
}
}

在这个例子中,我们创建了一个LoadingCache对象,并设置它的缓存大小为100,缓存数据的过期时间为1小时。当我们调用CACHE.get()方法时,如果缓存中没有对应的数据,则会使用loadDataFromDatabase()方法加载数据,并将加载的数据放入缓存中。

Cache Util

1
2
3
4
5
6
7
8
9
10
11
public class CacheUtil {

public static <K, V> LoadingCache<K, V> buildAsyncLoadingCache(long duration, TimeUnit unit , CacheLoader<K, V> cacheLoader) {
return CacheBuilder.newBuilder()
// 设置刷新缓存的时间
.refreshAfterWrite(duration , unit)
// 创建一个异步重加载的 CacheLoader ,需要实现其 load方法,定义如何去加载数据 , 使用 Executors 工具类新建一个 CacheThreadPool
.build(CacheLoader.asyncReloading(cacheLoader, Executors.newCachedThreadPool()));
}

}

Executors是Java中的一个工具类,它提供了一组工厂方法来创建常用的线程池对象。它包含多个静态工厂方法,可以方便地创建各种不同类型的线程池对象,例如:

  • newFixedThreadPool:创建一个固定大小的线程池。
  • newCachedThreadPool:创建一个可缓存的线程池。
  • newSingleThreadExecutor:创建一个单线程的线程池。

例如,下面的代码演示了如何使用Executors类创建一个可缓存的线程池:

1
2
3
4
5
6
7
8
9
public class ExecutorsExample {
public static void main(String[] args) {
// 创建一个可缓存的线程池
ExecutorService executor = Executors.newCachedThreadPool();

// 提交任务
executor.submit(new RunnableTask());
}
}

在这个例子中,我们使用Executors.newCachedThreadPool工厂方法创建了一个可缓存的线程池,并通过调用executor.submit()方法提交了一个任务。

需要注意的是,Executors类并不是线程安全的,因此,在多线程环境下使用时需要注意同步。

CacheThreadPool是一个可缓存的线程池。它通过重用存在的线程,提高了线程的复用率,并且可以有效地控制最大并发线程数。如果线程池中的所有线程都在运行任务,则新的任务将被放入队列中,等待线程被释放后执行。