Google Guava Cache 移除监听器

首先说明几点内容,以便更容易理解。

1:设置  expireAfterAccess(long, TimeUnit) 缓存元素在指定的时间没有被读取访问失效,或 设置 expireAfterWrite(long, TimeUnit) 缓存元素在指定的时间没有被写入访问失效,如果设置 removalListener(removalListener) 移除监听器,则失效元素在被移除时触发移除监听器。注意 设置元素的定时无操作失效后,元素并不会在时间到达后就主动失效触动移除监听器。而是在后续的访问或写入时,捎带着把先前放入的元素过期后进行驱逐。仔细想想这么做确实很巧妙。不用需要一个固定线程扫描缓存中的过期元素以免与用户的操作产生锁竞争。但是想让缓存中元素过期后就马上触发移除操作处理的就无能为力了。试想下,如果一个缓存设置元素5分钟无写入访问失效,那么5分钟之前写入缓存一个元素M,在接下来的5分钟之后如果没有对缓存的操作,那么这个元素就一直停留在缓存中,也不会触发移除监听,直到下次操作缓存时。

想要让缓存元素过期后就马上驱逐的,或过期后就触发移除监听器的,可以创建一个自己的维护线程,以固定的时间间隔调用 Cache.cleanUp(),现在问题来了,我以固定时间 间隔调用Cache.cleanUp() 触发了移除监听事件(说明移除了元素),但是在我后续的写入缓存操作时,又触发了次同一个元素的移除监听事件。知道原因的期待你的回答。

语言表述能力比较差,直接上代码

/*失效元素从缓存清除,监听事件 (同步通知)*/
	static RemovalListener<String, OrderInfo> removalListener = new RemovalListener<String, OrderInfo>() {
	    public void onRemoval(RemovalNotification<String, OrderInfo> notification) {
	    	OrderInfo orderInfo = notification.getValue();
	    	logger.info("remove cause " + notification.getCause() + " " + orderInfo.toString());
	    }
	};
/*订单缓存*/
	public static Cache<String, OrderInfo> cache = CacheBuilder.newBuilder()
			/*并发操作线程  默认4*/
			.concurrencyLevel(2)
			/*15秒无写入过期*/
		    .expireAfterWrite(15, TimeUnit.SECONDS)
		    /*最大元素个数1000, 元素个数接近临界点时,将按照LRU策略进行驱逐*/
		    .maximumSize(1000)
		    /*同步通知监听*/
		    .removalListener(removalListener)
		    /*异步通知监听*/
//		    .removalListener(removalListenerBuild())
		    .build();
/*周期性线程池*/
	private static ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
	
	protected void executeCleanCache() {
		
		/*参数说明
		 * 执行的线程任务
		 * 初始化延迟1分则后执行
		 * 每隔1分钟执行一次清除,本次执行结束后延迟1分钟开始下次执行
		 * 时间单位(分钟)
		 * */
		executorService.scheduleWithFixedDelay(new ClearUpExpired(), 1L, 1L, TimeUnit.MINUTES);
	}
	
	/**
	 * @Description: TODO 任务执行完毕之后,关闭调度线程池
	 * @author LWB
	 * create on 2014年12月22日  上午9:50:50
	 * @Title: shutdown void
	 */
	protected void shutdown() {
		executorService.shutdown();
	}
	
	/**
	 * @Description: TODO 立即关闭所有正在执行的线程
	 * @author LWB
	 * create on 2014年12月22日  上午9:53:16
	 * @Title: shutdownNow void
	 */
	protected void shutdownNow() {
		executorService.shutdownNow();
	}
	
	/**
	 * 清除过期的缓存元素
	 * @author  LWB
	 * @version 1.0
	 * Create on  2014年12月21日  下午10:01:18 
	 * 网络配货服务技术有限公司  Copyright©2014
	 */
	private class ClearUpExpired implements Runnable {

		@Override
		public void run() {
			cache.cleanUp();
		}
		
	}

日志为证

Google Guava Cache 移除监听器_第1张图片


你可能感兴趣的:(Google Guava Cache 移除监听器)