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;
}
}
运行后的结果以下:
第一次循环时缓存中没有数据,构建了缓存,第二次直接命中缓存。若是程序须要单机内存缓存,能够用该方式构建缓存。