HOWTO · Java

Java 中的内存缓存

本文讨论了在 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 以完成流。