Java 中的内存缓存
本教程将讨论我们可以在 Java 中用于内存缓存的两个库。
在 Java 中使用 Guava 库进行内存缓存
从 API 或数据库中获取数据时,如果我们希望频繁访问它,那么在需要时获取相同的数据可能会很昂贵。缓存变得很有用,因为它可以保存经常需要的数据,以便以后轻松访问。
为了在我们的项目中包含 Guava 库,我们使用以下 Maven 依赖项。
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>
例子:
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
public class ExampleClass1 {
private final LoadingCache<String, String> loadingCache;
public ExampleClass1() {
final CacheLoader<String, String> loader = new CacheLoader<>() {
@Override
public String load(String key) {
return key.toUpperCase();
}
};
loadingCache = CacheBuilder.newBuilder()
.maximumSize(1500)
.expireAfterAccess(15, TimeUnit.MINUTES)
.build(loader);
}
public static void main(String[] args) throws ExecutionException {
ExampleClass1 cacheExample = new ExampleClass1();
cacheExample.loadingCache.put("key1", "value1");
cacheExample.loadingCache.put("key2", "value2");
System.out.println("Whole cache as map: " + cacheExample.loadingCache.asMap());
System.out.println("Get a single value using a key: " + cacheExample.loadingCache.get("key1"));
}
}
输出:
Whole cache as map: {key1=value1, key2=value2}
Get a single value using key: value1
我们使用上面代码中键和值的类型参数创建了一个 LoadingCache
实例。在构造函数中,我们重写了计算和检索值的 CacheLoader
类的 load()
函数。
我们称 CacheBuilder
为 LoadingCache
的构建器。我们也调用 newBuilder()
方法。将缓存可以包含的最大值数和缓存的过期时间设置为访问后的 15 分钟。
然后我们用 loader
实例调用 build()
方法。为了从缓存中插入和获取数据,我们在 main()
方法中创建 ExampleClass1
的对象,并调用 put()
方法以键值对格式插入值。
我们可以使用 asMap()
方法将整个缓存作为地图获取,并且要从其键中获取单个值,我们使用 get()
函数并将键作为其参数。
在 Java 中使用 EhCache 库进行内存缓存
对于此示例,我们使用另一个名为 EhCache 的缓存库,我们可以使用以下 Maven 依赖项将其包含在项目中。
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.9.6</version>
</dependency>
例子:
import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;
public class ExampleClass1 {
public static void main(String[] args) {
CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
.withCache("exampleCache",
CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, String.class,
ResourcePoolsBuilder.heap(50))
.build()).build(true);
Cache<String, String> cache
= cacheManager.getCache("exampleCache", String.class, String.class);
cache.put("First Name", "Sam");
cache.put("Last Name", "Maxwell");
String getFirstNameFromCache = cache.get("First Name");
String getLastNameFromCache = cache.get("Last Name");
System.out.println("First Name: " + getFirstNameFromCache);
System.out.println("Last Name: " + getLastNameFromCache);
cacheManager.close();
}
}
输出:
[main] INFO org.ehcache.core.EhcacheManager - Cache 'exampleCache' created in EhcacheManager.
First Name: Sam
Last Name: Maxwell
[main] INFO org.ehcache.core.EhcacheManager - Cache 'exampleCache' removed from EhcacheManager.
正如我们所见,我们调用了 CacheManagerBuilder
类的 newCacheManagerBuilder()
方法。然后我们调用 withCache()
方法参数;第一个参数是缓存的别名,第二个参数是 CacheConfiguration
类型的缓存的配置。
我们使用 CacheConfigurationBuilder.newCacheConfigurationBuilder()
方法配置缓存,在该方法中我们传递键和值的类型。然后我们通过调用它的 build()
方法的堆大小。
最后,我们调用 CacheManagerBuilder
类的 build()
方法并传递 true,因为它的参数返回 CacheManager
的实例。
一旦设置了管理器,我们调用 getCache()
方法并传入别名和键值类型以获取返回 Cache
的缓存并带有类型参数。我们调用 put()
方法使用缓存对象以键值对的形式将值插入缓存。
我们使用 get()
方法从缓存中获取值。最后,我们关闭 cacheManager
以完成流。