-
Guava进修笔记:Guava cache
添加时间:2013-7-29 点击量:缓存,在我们日常开辟中是必不成少的一种解决机能题目的办法。简单的说,cache 就是为了提拔体系机能而开辟的一块内存空间。
缓存的首要感化是临时在内存中保存营业体系的数据处理惩罚成果,并且守候下次接见应用。在日常开辟的很多场合,因为受限于硬盘IO的机能或者我们自身营业体系的数据处理惩罚和获取可能很是费时,发明我们的体系这个数据恳求量很大的时辰,频繁的IO和频繁的逻辑处理惩罚会导致硬盘和CPU资料的瓶颈呈现。缓存的感化就是将这些来自不易的数据保存在内存中,当有其他线程或者客户端须要查询雷同的数据资料时,直接从缓存的内存块中返回数据,如许不单可以进步体系的响应时候,同时也可以节俭对这些数据的处理惩罚流程的资料消费,整体上来说,体系机能会有大大的提拔。
缓存在很多体系和架构中都用广泛的应用,例如:
1.CPU缓存
2.操纵体系缓存
3.本地缓存
4.分布式缓存
5.HTTP缓存
6.数据库缓存
等等,可以说在策画机和收集范畴,缓存无处不在。可以这么说,只要有硬件机能不合错误等,涉及到收集传输的处所都邑有缓存的身影。Guava Cache是一个全内存的本地缓存实现,它供给了线程安然的实现机制。整体上来说Guava cache 是本地缓存的不二之选,简单易用,机能好。
Guava Cache有两种创建体式格式:
1. cacheLoader
2. callable callback经由过程这两种办法创建的cache,和凡是用map来缓存的做法比,不合在于,这两种办法都实现了一种逻辑——从缓存中取key X的值,若是该值已经缓存过了,则返回缓存中的值,若是没有缓存过,可以经由过程某个办法来获取这个值。但不合的在于cacheloader的定义斗劲宽泛,是针对全部cache定义的,可以认为是同一的按照key值load value的办法。而callable的体式格式较为灵活,容许你在get的时辰指定。
cacheLoader体式格式实实际例:
@Test
public void TestLoadingCache() throws Exception{
LoadingCache<String,String> cahceBuilder=CacheBuilder
.newBuilder()
.build(new CacheLoader<String, String>(){
@Override
public String load(String key) throws Exception {
String strProValue=hello +key+!;
return strProValue;
}
});
System.out.println(jerry value:+cahceBuilder.apply(jerry));
System.out.println(jerry value:+cahceBuilder.get(jerry));
System.out.println(peida value:+cahceBuilder.get(peida));
System.out.println(peida value:+cahceBuilder.apply(peida));
System.out.println(lisa value:+cahceBuilder.apply(lisa));
cahceBuilder.put(harry, ssdded);
System.out.println(harry value:+cahceBuilder.get(harry));
}输出:
jerry value:hello jerry!
jerry value:hello jerry!
peida value:hello peida!
peida value:hello peida!
lisa value:hello lisa!
harry value:ssddedcallable callback的实现:
@Test
public void testcallableCache()throws Exception{
Cache<String, String> cache = CacheBuilder.newBuilder().maximumSize(1000).build();
String resultVal = cache.get(jerry, new Callable<String>() {
public String call() {
String strProValue=hello +jerry+!;
return strProValue;
}
});
System.out.println(jerry value : + resultVal);
resultVal = cache.get(peida, new Callable<String>() {
public String call() {
String strProValue=hello +peida+!;
return strProValue;
}
});
System.out.println(peida value : + resultVal);
}
输出:
jerry value : hello jerry!
peida value : hello peida!cache的参数申明:
收受接管的参数:
1. 大小的设置:CacheBuilder.maximumSize(long) CacheBuilder.weigher(Weigher) CacheBuilder.maxumumWeigher(long)
2. 时候:expireAfterAccess(long, TimeUnit) expireAfterWrite(long, TimeUnit)
3. 引用:CacheBuilder.weakKeys() CacheBuilder.weakValues() CacheBuilder.softValues()
4. 明白的删除:invalidate(key) invalidateAll(keys) invalidateAll()
5. 删除器:CacheBuilder.removalListener(RemovalListener)
refresh机制:
1. LoadingCache.refresh(K) 在生成新的value的时辰,旧的value依然会被应用。
2. CacheLoader.reload(K, V) 生成新的value过程中容许应用旧的value
3. CacheBuilder.refreshAfterWrite(long, TimeUnit) 主动刷新cache基于泛型的实现:
/
不须要延迟处理惩罚(泛型的体式格式封装)
@return
/
public <K , V> LoadingCache<K , V> cached(CacheLoader<K , V> cacheLoader) {
LoadingCache<K , V> cache = CacheBuilder
.newBuilder()
.maximumSize(2)
.weakKeys()
.softValues()
.refreshAfterWrite(120, TimeUnit.SECONDS)
.expireAfterWrite(10, TimeUnit.MINUTES)
.removalListener(new RemovalListener<K, V>(){
@Override
public void onRemoval(RemovalNotification<K, V> rn) {
System.out.println(rn.getKey()+被移除);
}})
.build(cacheLoader);
return cache;
}
/
经由过程key获取value
调用体式格式 commonCache.get(key) ; return String
@param key
@return
@throws Exception
/
public LoadingCache<String , String> commonCache(final String key) throws Exception{
LoadingCache<String , String> commonCache= cached(new CacheLoader<String , String>(){
@Override
public String load(String key) throws Exception {
return hello +key+!;
}
});
return commonCache;
}
@Test
public void testCache() throws Exception{
LoadingCache<String , String> commonCache=commonCache(peida);
System.out.println(peida:+commonCache.get(peida));
commonCache.apply(harry);
System.out.println(harry:+commonCache.get(harry));
commonCache.apply(lisa);
System.out.println(lisa:+commonCache.get(lisa));
}输出:
peida:hello peida!
harry:hello harry!
peida被移除
lisa:hello lisa!guava Cache数据移除:
guava做cache时辰数据的移除体式格式,在guava中数据的移除分为被动移除和主动移除两种。
文艺不是炫耀,不是花哨空洞的文字堆砌,不是一张又一张的逆光照片,不是将旅行的意义转化为名牌包和明信片的物质展示;很多时候它甚至完全不美——它嘶吼、扭曲,它会痛苦地抽搐,它常常无言地沉默。——艾小柯《文艺是一种信仰》
被动移除数据的体式格式,guava默认供给了三种体式格式:
1.基于大小的移除:看字面意思就知道就是遵守缓存的大小来移除,若是即将达到指定的大小,那就会把不常用的键值对从cache中移除。
定义的体式格式一般为 CacheBuilder.maximumSize(long),还有一种一种可以算权重的办法,小我认为实际应用中不太用到。就这个常用的来看有几个重视点,
其一,这个size指的是cache中的条目数,不是内存大小或是其他;
其二,并不是完全到了指定的size体系才开端移除不常用的数据的,而是接近这个size的时辰体系就会开端做移除的动作;
其三,若是一个键值对已经从缓存中被移除了,你再次恳求接见的时辰,若是cachebuild是应用cacheloader体式格式的,那依然还是会从cacheloader中再取一次值,若是如许还没有,就会抛出异常
2.基于时候的移除:guava供给了两个基于时候移除的办法
expireAfterAccess(long, TimeUnit) 这个办法是按照某个键值对最后一次接见之后几许时候后移除
expireAfterWrite(long, TimeUnit) 这个办法是按照某个键值对被创建或值被调换后几许时候移除
3.基于引用的移除:
这种移除体式格式主如果基于java的垃圾收受接管机制,按照键或者值的引用关系决意移除
主动移除数据体式格式,主动移除有三种办法:
1.零丁移除用 Cache.invalidate(key)
2.批量移除用 Cache.invalidateAll(keys)
3.移除所有效 Cache.invalidateAll()
若是须要在移除数据的时辰有所动作还可以定义Removal Listener,然则有点须要重视的是默认Removal Listener中的行动是和移除动作同步履行的,若是须要改成异步情势,可以推敲应用RemovalListeners.asynchronous(RemovalListener, utor)