Guava缓存器源码分析——删除消息
2013-09-20 20:45
375 查看
Guava缓存器的删除消息机制
测试代码——
测试结果:
因为缓存大小为3,依次查询到c时,缓存已满,当查询d时,a将被移除,当查询e时,b将被移除。
CacheBuilder的removalListener方法中,将其监听器参数赋值给成员变量removalListener,在LocalCache构造函数中,又传给LocalCache的删除监听器removalListener。至于removalNotificationQueue,也在LocalCache构造函数初始化:new ConcurrentLinkedQueue<RemovalNotification<K,
V>>()。
RemovalNotification为清除单条数据的通知,不管CacheBuilder中设置的键值引用级别是什么,此类保存的是键值的强引用,如果键值已经被垃圾回收器收集,则可能为空。
在引起缓存数据清除的操作中,都会将删除消息放入队列removalNotificationQueue中,入队主体函数: void enqueueNotification(K key, int hash, ValueReference<K, V> valueReference, RemovalCause cause)
参数cause表明引发此次删除操作的原因,为RemovalCause枚举类型,原因有以下几种:
1)EXPLICIT:键值被用户手动删除,当用户调用invalidate,invalidateAll,remove时, 会发生这种情况 。
2)REPLACED:键值发生替换。当用户调用put,refresh,putAll, replace时, 会发生这种情况 。
3)COLLECTED:垃圾回收引起键值被自动清除,在使用weakKeys,weakValues 或 softValues时, 会发生这种情况 。
4)EXPIRED:键值过期,在使用expireAfterAccess 或 expireAfterWrite时,会发生这种情况。
5)SIZE:缓存大小限制引起键值被清除,在使用maximumSize 或 maximumWeight时,会发生这种情况。
在入消息队列时,使用的是Queue的offer方法,如果队列已满,将返回false,而不会报IllegalStateException异常。
对删除消息的处理在下面函数中:
该函数被调用的过程如下:
只要涉及键值的读操作,都将执行postReadCleanup操作,每次执行postReadCleanup操作时readCount都增1,当其达到64时(DRAIN_THRESHOLD为0x3F,即0011 1111),引发cleanUp操作。
而只要涉及键值的写操作,都将执行postWriteCleanup操作。
测试代码——
LoadingCache<String, Integer> cache = CacheBuilder.newBuilder() .maximumSize(3) .expireAfterWrite(10, TimeUnit.SECONDS) .recordStats() .removalListener(new RemovalListener<String, Integer>() { @Override public void onRemoval(RemovalNotification<String, Integer> rn) { System.out.println(rn.getKey() + "被移除"); } }) .build( new CacheLoader<String, Integer>() { @Override public Integer load(String key) throws Exception { return num++; //初始值为1; } }); try { System.out.println(cache.get("a")); System.out.println(cache.get("b")); System.out.println(cache.get("c")); System.out.println(cache.get("d")); System.out.println(cache.get("e")); } catch (ExecutionException e) { e.printStackTrace(); }
测试结果:
因为缓存大小为3,依次查询到c时,缓存已满,当查询d时,a将被移除,当查询e时,b将被移除。
CacheBuilder的removalListener方法中,将其监听器参数赋值给成员变量removalListener,在LocalCache构造函数中,又传给LocalCache的删除监听器removalListener。至于removalNotificationQueue,也在LocalCache构造函数初始化:new ConcurrentLinkedQueue<RemovalNotification<K,
V>>()。
RemovalNotification为清除单条数据的通知,不管CacheBuilder中设置的键值引用级别是什么,此类保存的是键值的强引用,如果键值已经被垃圾回收器收集,则可能为空。
在引起缓存数据清除的操作中,都会将删除消息放入队列removalNotificationQueue中,入队主体函数: void enqueueNotification(K key, int hash, ValueReference<K, V> valueReference, RemovalCause cause)
参数cause表明引发此次删除操作的原因,为RemovalCause枚举类型,原因有以下几种:
1)EXPLICIT:键值被用户手动删除,当用户调用invalidate,invalidateAll,remove时, 会发生这种情况 。
2)REPLACED:键值发生替换。当用户调用put,refresh,putAll, replace时, 会发生这种情况 。
3)COLLECTED:垃圾回收引起键值被自动清除,在使用weakKeys,weakValues 或 softValues时, 会发生这种情况 。
4)EXPIRED:键值过期,在使用expireAfterAccess 或 expireAfterWrite时,会发生这种情况。
5)SIZE:缓存大小限制引起键值被清除,在使用maximumSize 或 maximumWeight时,会发生这种情况。
在入消息队列时,使用的是Queue的offer方法,如果队列已满,将返回false,而不会报IllegalStateException异常。
对删除消息的处理在下面函数中:
void processPendingNotifications() { RemovalNotification<K, V> notification; while ((notification = removalNotificationQueue.poll()) != null) { try { removalListener.onRemoval(notification); } catch (Throwable e) { logger.log(Level.WARNING, "Exception thrown by removal listener", e); } } }
该函数被调用的过程如下:
processPendingNotifications ←runUnlockedCleanup ←cleanUp(清零readCount) ←postReadCleanup(readCount增1) ←postWriteCleanup
只要涉及键值的读操作,都将执行postReadCleanup操作,每次执行postReadCleanup操作时readCount都增1,当其达到64时(DRAIN_THRESHOLD为0x3F,即0011 1111),引发cleanUp操作。
if ((readCount.incrementAndGet() & DRAIN_THRESHOLD) == 0) { cleanUp(); }
而只要涉及键值的写操作,都将执行postWriteCleanup操作。
相关文章推荐
- Guava缓存器源码分析——删除消息
- Guava缓存器源码分析――删除消息
- Guava缓存器源码分析——CacheBuilderSpec
- Guava缓存器源码分析——数据查询
- Guava缓存器源码分析——CacheBuilder
- Guava缓存器源码分析——缓存统计器
- Guava缓存器源码分析——LocalCache
- Guava缓存器源码分析——LocalCache
- [Guava源码分析](6)Objects分析
- OkHttp 3.7源码分析(四)——缓存策略
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- handler ,Looper的机制,分析源码(二)消息的收发
- Spring集成Spring-data-redis RedisCacheManager缓存源码分析
- Android SurfaceFlinger服务的消息循环过程源码分析
- lodash源码分析之List缓存
- 源码分析RocketMQ消息消费机制----消费端消息负载均衡机制与重新分布
- Android异步消息机制及源码分析
- Android 消息处理机制2(从源码分析)
- android的消息处理机制(图+源码分析)——Looper,Handler,Message
- 4000 LDD3源码分析之slab高速缓存