Guava Cache的使用

Guava Cache与ConcurrentHashMap很相似,区别在于Guava Cache能设置回收,解决了大数据缓存导致的内存溢出问题

Guava Cache的回收方式有三种:基于容量回收、定时回收和基于引用回收

具体介绍参照:http://ifeve.com/google-guava-cachesexplained/

上测试代码:

public class CacheTest {

	public static void main(String[] args) {
		for (int i = 0; i < 2; i++) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					try {
						testLoadCache("key1", "key2");
					} catch (ExecutionException e) {
						e.printStackTrace();
					}
				}
			}).start();
		}
	}

	private static int index = 0;
//	这里设置了初始容量为16,缓存有效期1S
	private static LoadingCache<String, String> lCache = CacheBuilder.newBuilder().initialCapacity(16).expireAfterAccess(1, TimeUnit.SECONDS)
			.build(new CacheLoader<String, String>() {
//				默认的数据加载实现,当调用get取值时,如果key没有对应的值,则调用此方法进行加载。如果get方法指定了Callable则调用call方法来替换
				@Override
				public String load(String key) throws Exception {
					System.out.println(
							Thread.currentThread().getName() + " compute , load index================== " + index++);
					return "load-default";
				}
			});

	public static void testLoadCache(String key, String key2) throws ExecutionException {
		
//		创建get中使用的覆盖Callable对象
		Callable<String> callable = new Callable<String>() {
			@Override
			public String call() throws Exception {
				System.out.println(
						Thread.currentThread().getName() + " compute , call index================== " + index++);
				return "call-overwrite";
			}
		};
//		获取数据,如果没有key对应的值则调用load加载并返回加载出来的值
		String value = lCache.get(key);
//		获取数据,如果没有key对应的值则调用Call加载并返回加载出来的值,这里的call覆盖了load加载
		String value2 = lCache.get(key2, callable);
		System.out.println(Thread.currentThread().getName() + "-------------" + value);
		System.out.println(Thread.currentThread().getName() + "=============    " + value2);
		try {
//			睡眠2S用于测试缓存有效期
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("\n*****************************************************\n");
//		缓存中数据已经被回收清理,此处将重新进行加载
		value = lCache.get(key);
		value2 = lCache.get(key2, callable);
		System.out.println(Thread.currentThread().getName() + "-------------" + value);
		System.out.println(Thread.currentThread().getName() + "=============    " + value2);
	}

}
执行结果
Thread-1 compute , load index================== 0
Thread-1 compute , call index================== 1
Thread-1-------------load-default
Thread-1============= call-overwrite
Thread-2-------------load-default
Thread-2============= call-overwrite

*****************************************************


*****************************************************

Thread-1 compute , load index================== 2
Thread-1 compute , call index================== 3
Thread-1-------------load-default
Thread-1============= call-overwrite
Thread-2-------------load-default
Thread-2============= call-overwrite

发现超时后缓存被回收,当再使用时又重新进行初始化加载...

可以使用Guava Cache来替换ConcurrentHashMap进行数据缓存,即能满足高并发缓存读写,又解决了缓存过大导致的内存溢出 

猜你喜欢

转载自longe-d.iteye.com/blog/2315518