java中的本地緩存GuavaCache使用方法和示例教程
在現(xiàn)代互聯(lián)網(wǎng)應(yīng)用中,高并發(fā)場景是每個開發(fā)者都可能遇到的挑戰(zhàn)。為了提高系統(tǒng)的響應(yīng)速度和吞吐量,緩存技術(shù)成為了一個不可或缺的部分。Google Guava庫提供了一個強大的本地緩存實現(xiàn)——GuavaCache,它不僅簡單易用,而且性能優(yōu)秀,非常適合處理高并發(fā)場景。
GuavaCache簡介
GuavaCache是Google Guava庫中的一個組件,用于實現(xiàn)內(nèi)存中的緩存。它支持多種配置選項,如設(shè)置緩存大小、過期策略等,并且提供了線程安全的操作方法,使得在多線程環(huán)境中使用更加方便。
主要特性
線程安全
GuavaCache的所有操作都是線程安全的,這使得它在高并發(fā)環(huán)境下能夠穩(wěn)定運行,無需額外的同步控制。
自動加載
可以通過LoadingCache接口實現(xiàn)數(shù)據(jù)的自動加載,當緩存中沒有找到對應(yīng)的鍵時,會自動調(diào)用指定的方法來加載數(shù)據(jù)。
過期策略
支持基于時間的過期策略,包括創(chuàng)建后過期(expire after write)和訪問后過期(expire after access)。
內(nèi)存回收
GuavaCache可以根據(jù)內(nèi)存情況自動回收不常用的條目,避免內(nèi)存溢出。
使用示例
基本使用
首先,需要添加Guava庫到項目中,如果使用Maven,可以在pom.xml中添加如下依賴:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>接下來,創(chuàng)建一個簡單的緩存實例:
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 GuavaCacheExample {
public static void main(String[] args) throws ExecutionException {
// 創(chuàng)建一個LoadingCache實例
LoadingCache<String, String> cache = CacheBuilder.newBuilder()
.maximumSize(100) // 設(shè)置緩存的最大容量
.expireAfterWrite(10, TimeUnit.MINUTES) // 設(shè)置過期時間為10分鐘
.build(new CacheLoader<String, String>() { // 定義默認的數(shù)據(jù)加載機制
@Override
public String load(String key) throws Exception {
return "value-" + key;
}
});
// 訪問緩存
String value = cache.get("key1");
System.out.println(value); // 輸出: value-key1
}
}異常處理
在實際應(yīng)用中,數(shù)據(jù)加載可能會拋出異常。GuavaCache允許你定義如何處理這些異常:
try {
String value = cache.get("key2");
} catch (ExecutionException e) {
// 處理異常
System.err.println("Failed to load value for key2: " + e.getCause());
}手動加載和刪除
除了自動加載外,還可以手動將數(shù)據(jù)放入緩存或從緩存中刪除數(shù)據(jù):
// 手動加載
cache.put("key3", "value3");
// 手動刪除
cache.invalidate("key3");性能優(yōu)化
并發(fā)級別
通過設(shè)置concurrencyLevel參數(shù)可以調(diào)整緩存的并發(fā)性能,這個值表示預(yù)計同時訪問緩存的線程數(shù)。通常情況下,默認值已經(jīng)足夠好,但在特定場景下適當調(diào)整可以提升性能。
軟引用與弱引用
對于內(nèi)存敏感的應(yīng)用,可以考慮使用軟引用或弱引用來存儲緩存項,這樣當系統(tǒng)內(nèi)存不足時,JVM會自動回收這些對象。
CacheBuilder.newBuilder()
.softValues() // 使用軟引用
.weakKeys() // 使用弱引用
.build();GuavaCache是一個強大而靈活的緩存工具,特別適合于需要高性能和低延遲的應(yīng)用。通過合理配置,可以有效應(yīng)對高并發(fā)場景下的各種挑戰(zhàn)。這篇文章介紹了GuavaCache的基本概念、主要特性和使用方法,以及一些性能優(yōu)化的技巧,適合對緩存技術(shù)感興趣的開發(fā)者閱讀。Guava Cache 是一個非常高效的本地緩存庫,特別適合處理高并發(fā)場景。下面是一個使用 Guava Cache 的示例代碼,假設(shè)我們有一個需要頻繁查詢用戶信息的應(yīng)用場景。
場景描述
假設(shè)我們有一個用戶服務(wù),需要頻繁地從數(shù)據(jù)庫中查詢用戶信息。為了減少數(shù)據(jù)庫的訪問壓力,我們可以使用 Guava Cache 來緩存用戶信息。
依賴引入
首先,確保你的項目中已經(jīng)引入了 Guava 庫。如果你使用的是 Maven,可以在 pom.xml 中添加以下依賴:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.0.1-jre</version>
</dependency>示例代碼
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
public class UserCacheService {
// 創(chuàng)建一個 Guava Cache 實例
private final Cache<String, User> userCache;
public UserCacheService() {
// 配置緩存
this.userCache = CacheBuilder.newBuilder()
.maximumSize(1000) // 最大緩存條目數(shù)
.expireAfterWrite(10, TimeUnit.MINUTES) // 緩存條目在寫入后 10 分鐘過期
.recordStats() // 記錄緩存統(tǒng)計信息
.build();
}
// 獲取用戶信息
public User getUser(String userId) {
try {
return userCache.get(userId, () -> loadUserFromDatabase(userId));
} catch (ExecutionException e) {
throw new RuntimeException("Failed to load user from cache", e);
}
}
// 從數(shù)據(jù)庫加載用戶信息
private User loadUserFromDatabase(String userId) {
// 模擬從數(shù)據(jù)庫加載用戶信息
System.out.println("Loading user " + userId + " from database");
return new User(userId, "User Name " + userId);
}
public static void main(String[] args) {
UserCacheService service = new UserCacheService();
// 模擬高并發(fā)請求
for (int i = 0; i < 10; i++) {
new Thread(() -> {
User user = service.getUser("12345");
System.out.println("User: " + user);
}).start();
}
}
}
class User {
private String id;
private String name;
public User(String id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "User{id='" + id + "', name='" + name + "'}";
}
}代碼解釋
- 緩存配置:
maximumSize(1000):設(shè)置緩存的最大條目數(shù)為 1000。expireAfterWrite(10, TimeUnit.MINUTES):設(shè)置緩存條目在寫入后 10 分鐘過期。recordStats():記錄緩存的統(tǒng)計信息,方便監(jiān)控和調(diào)試。
- 獲取用戶信息:
getUser方法通過userCache.get方法從緩存中獲取用戶信息。如果緩存中沒有該用戶信息,則調(diào)用loadUserFromDatabase方法從數(shù)據(jù)庫中加載用戶信息,并將其存入緩存。
- 從數(shù)據(jù)庫加載用戶信息:
loadUserFromDatabase方法模擬從數(shù)據(jù)庫中加載用戶信息的過程。
- 模擬高并發(fā)請求:
- 在
main方法中,創(chuàng)建多個線程模擬高并發(fā)請求,每個線程都嘗試獲取同一個用戶的用戶信息。由于緩存的存在,多次請求只會觸發(fā)一次數(shù)據(jù)庫查詢。
備注
1. 基本概念
- Cache:Guava Cache的主要接口,用于定義緩存的基本操作,如獲取、插入和刪除緩存項。
- LoadingCache:繼承自
Cache,提供了一種自動加載數(shù)據(jù)到緩存中的機制,當緩存中沒有請求的數(shù)據(jù)時,可以自動從數(shù)據(jù)源加載。 - RemovalListener:監(jiān)聽器接口,用于監(jiān)聽緩存項的移除事件,可以實現(xiàn)一些清理工作或日志記錄。
2. 創(chuàng)建Guava Cache
創(chuàng)建一個簡單的GuavaCache可以通過CacheBuilder來完成。以下是一個基本的例子:
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.util.concurrent.TimeUnit;
public class GuavaCacheExample {
public static void main(String[] args) {
// 創(chuàng)建一個最大容量為100,超過容量后使用LRU算法移除最近最少使用的條目,
// 并且設(shè)置10分鐘后過期的緩存
Cache<String, String> cache = CacheBuilder.newBuilder()
.maximumSize(100)
.expireAfterWrite(10, TimeUnit.MINUTES)
.removalListener(notification -> System.out.println("Removed: " + notification.getKey()))
.build();
// 向緩存中添加數(shù)據(jù)
cache.put("key1", "value1");
// 從緩存中獲取數(shù)據(jù)
String value = cache.getIfPresent("key1");
System.out.println(value); // 輸出: value1
}
}3. 使用LoadingCache
LoadingCache可以在緩存未命中時自動加載數(shù)據(jù),這通常通過實現(xiàn)CacheLoader來完成:
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
public class LoadingCacheExample {
public static void main(String[] args) throws ExecutionException {
LoadingCache<String, String> cache = CacheBuilder.newBuilder()
.maximumSize(100)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(new CacheLoader<String, String>() {
@Override
public String load(String key) throws Exception {
return fetchFromDatabase(key);
}
});
// 獲取數(shù)據(jù),如果緩存中沒有,會自動調(diào)用load方法加載
String value = cache.get("key1");
System.out.println(value); // 輸出: 從數(shù)據(jù)庫獲取的數(shù)據(jù)
}
private static String fetchFromDatabase(String key) {
// 模擬從數(shù)據(jù)庫查詢
return "從數(shù)據(jù)庫獲取的數(shù)據(jù)";
}
}4. 高級特性
- 統(tǒng)計信息:通過
cache.stats()可以獲得緩存的統(tǒng)計信息,如命中率、加載失敗次數(shù)等。 - 異步加載:可以使用
getUnchecked或getAll方法進行異步加載,適合于耗時較長的操作。 - 刷新策略:通過
refreshAfterWrite方法可以設(shè)置緩存項在寫入后的多久時間后刷新。
5. 注意事項
- 線程安全:Guava Cache是線程安全的,多線程環(huán)境下的讀寫操作不需要額外的同步控制。
- 內(nèi)存占用:雖然Guava Cache提供了多種策略來控制緩存大小,但在高并發(fā)場景下仍需注意內(nèi)存使用情況,避免因內(nèi)存溢出導(dǎo)致應(yīng)用崩潰。
- 過期策略:合理設(shè)置過期時間和清除策略,避免緩存中的數(shù)據(jù)長時間不更新,導(dǎo)致數(shù)據(jù)陳舊。
總結(jié)
通過使用 Guava Cache,我們可以有效地減少對數(shù)據(jù)庫的訪問次數(shù),提高系統(tǒng)的性能和響應(yīng)速度。特別是在高并發(fā)場景下,緩存的作用更加明顯。希望這個示例對你有所幫助!在處理高并發(fā)場景時,緩存是提高系統(tǒng)性能和響應(yīng)速度的重要手段之一。Google Guava庫提供了一個非常強大的本地緩存實現(xiàn)——GuavaCache,它不僅提供了基本的緩存功能,還支持多種高級特性,如過期策略、大小限制、統(tǒng)計信息等,非常適合在高并發(fā)環(huán)境下使用。
到此這篇關(guān)于java中的本地緩存GuavaCache使用方法和示例教程的文章就介紹到這了,更多相關(guān)java本地緩存GuavaCache內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java使用注解實現(xiàn)BigDecimal的四舍五入
BigDecimal是Java中的一個類,位于java.math包中,它提供了任意精度的有符號十進制數(shù)字的表示,以及對這些數(shù)字進行算術(shù)運算的方法,本文介紹了Java使用注解實現(xiàn)BigDecimal的四舍五入的相關(guān)知識,需要的朋友可以參考下2024-09-09
SpringMVC?RESTFul實戰(zhàn)案例修改功能實現(xiàn)
這篇文章主要為大家介紹了SpringMVC?RESTFul實戰(zhàn)案例修改功能實現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-05-05

