1 2
►
Go
共有 19 回复( 2页) 阅读509次
|
|
|
|
|
|
近日模仿了Jive中的Cache,自己做了一个通用的Cache系统。于是牵涉到了一些同步问题。 我发现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 cacheType,Object key){ Cache cache = (Cache)cacheList.get(cacheType); if(cache == null){ synchronized(cacheType){ //这里保证cacheType是全局且唯一的 cache = (Cache)cacheList.get(cacheType); if(cache == null){ cache = new Cache(105,lifeTime); } } }
|
上面的代码是根据CacheType从一个HashMap中去get()某个Cache。 由于DCL不成立,所以上面的代码无法保证同步 (具体参见http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html)
那么,我改动成为这样以后,是否可以了呢?
Class CacheManager{ ... private static Cache reservedCache = new Cache(); ......
public static Object getObject(Object type,Object key){
public static Object getObject(Object cacheType,Object key){ Cache cache = (Cache)cacheList.get(cacheType); if(cache == null){ synchronized(cacheType){ //这里保证cacheType是全局且唯一的 cache = (Cache)cacheList.get(cacheType); if(cache == null){ cache = reservedCache; reservedCache = new Cache(105,lifeTime); } } } }
|
:)
|
|
|
|
|
|
Re: 再谈Double Check Lock!
|
2003年05月11日 13:17
|
|
|
<<java与模式>>中指出dcl在java中不可用。 具体原因没有说太清楚。
|
|
|
|
|
|
Re: 再谈Double Check Lock!
|
2003年05月12日 23:36
|
|
|
what's the relationship between reserverCache and cachelist in your code? if you later put reserverCache into cachelist at the end of synch block, I guess it's fine as there is no crossing point among threads before that. Here is another article on DCL: http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-double-p2.html
|
|
|
|
|
|
Re: 再谈Double Check Lock!
|
2003年05月13日 19:44
|
|
|
> what's the relationship between reserverCache and > cachelist in your code? cacheList是一个HashMap,Key是public static final Integer,代表保存Cache的类型,Value是Cache Object.
而Cache内部也用了一个HashMap而已,只不过Cache::get/set同步了而已。
>if you later put > reserverCache into cachelist at the end of synch > block, I guess it's fine as there is no crossing > point among threads before that. 我就在想,引用之间的赋值应该是原子操作的吧?
|
|
|
|
|
|
Re: 再谈Double Check Lock!
|
2003年05月13日 20:11
|
|
|
这篇文章偶看过了,偶现在就用static singlton。不过不知道如果把我的程序移到了集群的AppServer上以后,会怎么样。。。。好多Singleton的。。。汗ing...
偶要是全部synchronized起来,那么1CPU和4CPU还有什么区别呢?
看起来,用Java写多线程容易,但是要写好也不是那么容易了,基本上已经和用C++处于同一个水平层次咯。或者说和语言差不多无关咯~~~ 重要的是要知道点系统结构,汇编咯,否则自己死到那里取都不知道错在咯~~~
|
|
|
|
|
|
Re: 再谈Double Check Lock!
|
2003年05月16日 16:01
|
|
|
effective java中文版一书中,在165页明确指明了Double Check Lock不能正确执行工作!!!
请大家参见该书!!!
|
|
|
|
|
|
Re: 再谈Double Check Lock!
|
2003年05月22日 12:01
|
|
|
> 近日模仿了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了,于是有可能别的线程进入一个没有初始化(构造函数).........
所以那些代码好像都不能解决这个根本问题
不知道我的理解对不对
|
|
|
|
|
|
Re: 再谈Double Check Lock!
|
2003年05月26日 09:10
|
|
|
确实如此,java的对象初始化并不是向我们想象的那样按顺序初始化的, 所以dcl在java中是不成立的。
|
|
|
|
|
|
Re: 再谈Double Check Lock!
|
2003年05月26日 09:27
|
|
|
|
近来看OFBiz的源码, 发现其大量运用了dcl, 以前看jive时发现它用的也比较多, 如果要在这些开源项目的基础上做自己的应用, 岂不是很危险?
|
|
|
|
|
|
Re: 再谈Double Check Lock!
|
2003年06月16日 10:52
|
|
|
|
实际上sun和ibm的jdk都没有问题,可以成立,可能有的jdk,或者比较早的jdk不行保证,呵呵
|
|
|
|
|
|
Re: 再谈Double Check Lock!
|
2003年06月27日 10:07
|
|
|
大家讨论的这段代码是一个DCL问题吗?
代码中的CACHE根本就不是全局的,而是一个局域变量。不管是单还是多线程都不会有问题
|
|
|
|
|
|
Re: 再谈Double Check Lock!
|
2003年06月27日 21:41
|
|
|
> 大家讨论的这段代码是一个DCL问题吗? > > 代码中的CACHE根本就不是全局的,而是一个局域变量。不管?> 单还是多线程都不会有问题
Cache refrence是局部的.Cache实例是全局的
|
|
|
|
|
|
Re: 再谈Double Check Lock!
|
2003年06月30日 13:46
|
|
|
|
|
|
|
|
|
Re: 再谈Double Check Lock!
|
2003年07月30日 00:05
|
|
|
|
老早就看到这些文章,也想在性能和安全方面做个取舍,不过还是偏向于采用DCL,性能搞一点。我想大家用的时候还是做个并发压力测试吧,只要自己用的没问题也就行了。不知道有没有朋友亲自验证过这个DCL出问题的状况?
|
|
|
|
|
|
Re: 再谈Double Check Lock!
|
2003年07月30日 17:52
|
|
|
> 老早就看到这些文章,也想在性能和安全方面做个取舍,不过 > 故瞧蛴诓捎DCL,性能搞一点。我想大家用的时候还是做个 > ⒎⒀沽Σ馐园桑灰约河玫拿晃侍庖簿托辛恕2恢烙忻挥 > 朋友亲自验证过这个DCL出问题的状况?
就实践来看,我只用SunJDK/IBM JDK,我也跑过一些专门测试DCL是否成功 的TestCase,看起来好象都没有问题,至于其他的JVM就不清楚了。一切都在于JMM的错
|
|
|
|