Guava是Google guava中的一個內存緩存模塊,用於將數據緩存到JVM內存中。實際項目開發中常常將一些公共或者經常使用的數據緩存起來方便快速訪問。java
Guava Cache是單個應用運行時的本地緩存。它不把數據存放到文件或外部服務器。若是不符合需求,能夠選擇Memcached、Redis等工具。git
pom.xml添加guava依賴github
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>me.xueyao.cache</groupId> <artifactId>java-demo</artifactId> <version>1.0.0</version> <dependencies> <dependency> <groupId>javax.cache</groupId> <artifactId>cache-api</artifactId> <version>1.1.0</version> </dependency> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>27.0.1-jre</version> </dependency> </dependencies> </project>
GuavaCacheDemo.java 代碼以下:算法
package me.xueyao.cache.java.guava; import com.google.common.cache.*; import me.xueyao.cache.java.pojo.User; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; /** * @author simon * https://github.com/google/guava */ public class GuavaCacheDemo { public static void main(String[] args) throws ExecutionException { //緩存接口這裏是LoadingCache,LoadingCache在緩存項不存在時能夠自動加載緩存 LoadingCache<String, User> userCache //CacheBuilder的構造函數是私有的,只能經過其靜態方法newBuilder()來得到CacheBuilder的實例 = CacheBuilder.newBuilder() //設置併發級別爲8,併發級別是指能夠同時寫緩存的線程數 .concurrencyLevel(8) //設置寫緩存後8秒鐘過時 .expireAfterWrite(8, TimeUnit.SECONDS) //設置寫緩存後1秒鐘刷新 .refreshAfterWrite(1, TimeUnit.SECONDS) //設置緩存容器的初始容量爲5 .initialCapacity(5) //設置緩存最大容量爲100,超過100以後就會按照LRU最近雖少使用算法來移除緩存項 .maximumSize(100) //設置要統計緩存的命中率 .recordStats() //設置緩存的移除通知 .removalListener(new RemovalListener<Object, Object>() { @Override public void onRemoval(RemovalNotification<Object, Object> notification) { System.out.println(notification.getKey() + " 被移除了,緣由: " + notification.getCause()); } }) //build方法中能夠指定CacheLoader,在緩存不存在時經過CacheLoader的實現自動加載緩存 .build( new CacheLoader<String, User>() { @Override public User load(String key) throws Exception { System.out.println("緩存沒有時,從數據庫加載" + key); return new User("tony" + key, key); } } ); // 第一次讀取 for (int i = 0; i < 10; i++) { User user = userCache.get("uid" + i); System.out.println(user); } // 第二次讀取 for (int i = 0; i < 10; i++) { User user = userCache.get("uid" + i); System.out.println(user); } System.out.println("cache stats:"); //最後打印緩存的命中率等 狀況 System.out.println(userCache.stats().toString()); } }
User.java 代碼以下:數據庫
package me.xueyao.cache.java.pojo;
import java.io.Serializable;apache
/**api
@author simon
*/
public class User implements Serializable {
private String userName;
private String userId;緩存
public User(String userName, String userId) {
this.userName = userName;
this.userId = userId;
}服務器
public String getUserId() {
return userId;
}併發
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
@Override
public String toString() {
return userId + " --- " + userName;
}
}
運行後的結果以下:
第一次循環時緩存中沒有數據,構建了緩存,第二次直接命中緩存。若是程序須要單機內存緩存,能夠用該方式構建緩存。