> 近日模仿了Jive中的Cache,自己做了一个通用的Cache系统。
> 谑乔I娴搅艘恍┩轿侍狻?> 我发现Jive中好多地方用到了Double Check Lock.
> 我看了一些相关的文档,应该说DCL是在Java中不成立的。
> 那么我现在这段代码大家看看,能否使用呢?
>
>
> /** > * Get object from cache > * @param type object type > * @param key object ID as key in cache > * @return Object > */ > public static Object getObject(Object > ct cacheType,Object key){ > Cache cache = > he cache = (Cache)cacheList.get(cacheType); > if(cache == null){ > synchronized(cacheType){ > ed(cacheType){ //这里保证cacheType是全局且唯一的 > cache = > cache = (Cache)cacheList.get(cacheType); > if(cache == null){ > cache = new > cache = new Cache(105,lifeTime); > } > } > } >
|
>
> 上面的代码是根据CacheType从一个HashMap中去get()某个Cac
> e。
> 由于DCL不成立,所以上面的代码无法保证同步
> (具体参见http://www.cs.umd.edu/~pugh/java/memoryModel
> DoubleCheckedLocking.html)
>
> 那么,我改动成为这样以后,是否可以了呢?
> > Class CacheManager{ > ... > private static Cache reservedCache = new > new Cache(); > ...... > > public static Object getObject(Object type,Object > ct key){ > > public static Object getObject(Object > ct cacheType,Object key){ > Cache cache = > he cache = (Cache)cacheList.get(cacheType); > if(cache == null){ > synchronized(cacheType){ > ed(cacheType){ //这里保证cacheType是全局且唯一的 > cache = > cache = (Cache)cacheList.get(cacheType); > if(cache == null){ > cache = reservedCache; > reservedCache = new > reservedCache = new Cache(105,lifeTime); > } > } > } > } >
|
> :)
忘记了在哪里看到的,DCL的根本原因是new这个操作在java里不是一个原子操作,分为两步,一步为分配内存空间,一步为初始化.这是在java语言规范中规定的,不同的JVM可能实现不同.
第一步完成之后,cache已经不是null了,于是有可能别的线程进入一个没有初始化(构造函数).........
所以那些代码好像都不能解决这个根本问题
不知道我的理解对不对