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 以完成流。