论坛首页 Java企业应用论坛

缓存框架之AOP渐进实现

浏览 12932 次
精华帖 (1) :: 良好帖 (3) :: 新手帖 (0) :: 隐藏帖 (7)
作者 正文
   发表时间:2010-07-20   最后修改:2010-07-20
OK,Cache层如何扩展并不是本篇的主题,我所提供的只是一个参照解决方案,大家完全可以自己去扩展实现。至于线程安全问题并不是要在cache上加锁,而是cacheName+cacheKey,实现方式可以将cache包装一层提供一个getAndPut的原子方法,可以参考AtomicInteger,或者如我回复的那样加双重检查(如下代码所示),毕竟CacheKey是一个保护类,小概率事件是不太会发生的.
Object value = findFromCache(policy.getCacheName(), cacheKey);
		if (value == null) {
			value = synchronizedExecutor.synchronizedExecute(new Callable<Object>() {

				@Override
				public Object call() throws Exception {
					Object value = findFromCache(policy.getCacheName(), cacheKey);
					if (value == null) {
						try {
							value = methodInvocation.proceed();
							putInCache(policy, cacheKey, value);
						} catch (Throwable e) {
							throw new Exception(e);
						}
					}
					return value;
				}

			}, Maps.immutableEntry(policy.getCacheName(), cacheKey))
0 请登录后投票
   发表时间:2010-07-20   最后修改:2010-07-20
1 cache本身没有读写控制?
2 methodInvocation.proceed()执行的时候,cache可以读写吗?
3 多个线程可以以不同的参数,同时调用methodInvocation.proceed()?
4 这样double check多少影响些性能。
0 请登录后投票
   发表时间:2010-07-20   最后修改:2010-07-20
不错的,最近正在做这方面的东西,谢谢共享
0 请登录后投票
   发表时间:2010-07-20  
哎,先看看这个
http://www.iteye.com/topic/670414

Google Collections 中的MapMaker就可以当缓存用
0 请登录后投票
   发表时间:2010-07-20  
rain2005 写道
哎,先看看这个
http://www.iteye.com/topic/670414

Google Collections 中的MapMaker就可以当缓存用

MapMaker的代码没有具体看过,不过有个疑问:
ComputingMap的Function在执行过程中,缓存是否可以读写?
1 如果不能,那么影响并发性能。
2 如果可以,那么多个线程可能同时以相同name调用Function,如果这些调用的返回值不同,那么ComputingMap无法知道到底那个返回值是最新版本。
0 请登录后投票
   发表时间:2010-07-20  
whitesock 写道
rain2005 写道
哎,先看看这个
http://www.iteye.com/topic/670414

Google Collections 中的MapMaker就可以当缓存用

MapMaker的代码没有具体看过,不过有个疑问:
ComputingMap的Function在执行过程中,缓存是否可以读写?
1 如果不能,那么影响并发性能。
2 如果可以,那么多个线程可能同时以相同name调用Function,如果这些调用的返回值不同,那么ComputingMap无法知道到底那个返回值是最新版本。



在仔细看下吧,Concurrent Map,线程安全的,没有问题的。
0 请登录后投票
   发表时间:2010-07-20   最后修改:2010-07-20
最大的好处是,弱引用版本的ConcurrentHashMap,gc友好,并发安全。
0 请登录后投票
   发表时间:2010-07-20   最后修改:2010-07-20
你没看明白。
ConcurrentHashMap线程安全不代表对Function的调用也是安全的。如果get方法中发现不命中,那么调用function。问题在于对这个Function的调用时,是否持有ConcurrentHashMap的锁?(ConcurrentHashMap在get方法中其实没有加锁)
1 如果是,那么影响并发性能。
2 如果不是,那么多个线程可能同时以相同name调用Function,如果这些调用的返回值不同,那么ConcurrentHashMap无法知道到底那个返回值是最新版本。也就无法保证put的数据是正确的。
0 请登录后投票
   发表时间:2010-07-21  
关注一下后续的讨论。这个话题我很感兴趣
0 请登录后投票
   发表时间:2010-07-21  
whitesock 说的场景可以概括成:

A、B、C代表线程

A从缓存中获取了i(10),然后减1,把10-1=9放入缓存;

B从缓存中获取了i(10),然后加1,把10+1=11放入缓存;

C从缓存中获取了i(10),然后乘2,把10*2=20放入缓存;

问题就是,不清楚A、B、C何时结束,所以也就不知道9、11、20哪个是最新的数据了。

如果要保证更新是按照多线程触发的顺序来的话,那么应该是对i加锁,而不是应该在Cache的get和put上加锁。

对i加锁的意思是,加、减、乘都是i的方法,在这些方法上加锁。

此时Cache只需要知道最后调用的put是最新数据就可以了。

不知道我的理解对不对
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics