锁定老帖子 主题:对于单例模式的一点想法
精华帖 (1) :: 良好帖 (9) :: 新手帖 (11) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-07-14
spiritfrog 写道 这贴为什么给新手帖这么多?
难道都理解了? ibm这篇http://www.ibm.com/developerworks/java/library/j-dcl.html out-of-order writes往后,就很难看下去了。 因为这里的很多人很浮躁,以为这么简单的问题自己早就知道了。其实是错的。 |
|
返回顶楼 | |
发表时间:2008-07-14
Lucas Lee 写道 biubiu 写道 除了你已经提出的两种办法,没有其他可以run everywhere的办法了。
我最后提出的一种方案不行么? 看看附件的文章。最后的结论是: “Best practice is that if a variable is ever to be assigned by one thread and used or assigned by another, then all accesses to that variable should be enclosed in synchronized methods or synchronized statements.” |
|
返回顶楼 | |
发表时间:2008-07-14
单例模式用在java web问题多多。
|
|
返回顶楼 | |
发表时间:2008-07-14
用Enum
|
|
返回顶楼 | |
发表时间:2008-07-15
netrice 写道 public static SysRoleDAO getInstance() { if (sysRole == null) { synchronized (SysRoleDAO.class) { if (sysRole == null) { SysRoleDAO _sysRole = new SysRoleDAO(); sysRole = _sysRole; } } } return sysRole; } 试试这样 这个跟LZ的最后一种方法类似 只是如果JIT连sysRole = _sysRole;也优化的话 那就又有问题了 |
|
返回顶楼 | |
发表时间:2008-07-15
不要是试图使用双重检查来 解决这个问题。 在java与模式中作者讲得很明白了。 在多线程的程序中,只能尽量降低同步的几率来保证单例的唯一性。 下面这这样就就是基于上面的理由。 private static HashCodeDigest instance = null; private HashCodeDigest() { } private static synchronized void syncInit() { if (instance == null) { instance = new HashCodeDigest(); } } public static HashCodeDigest getInstance() { if (instance == null) { syncInit(); } return instance; } 而这样做你是完全依赖于双重检查。 private static Singleton INSTANCE; public static Singleton getInstance(){ if(INSTANCE==null){ synchronized(Singelton.class){ //Double checking if(INSTANCE==null){ INSTANCE=new Singleton(); } } } } |
|
返回顶楼 | |
发表时间:2008-07-15
既然在分布式应用中不赞成使用singleton。
那么如何在分布式应用中使用某种方式, 达到类似singleton的效果? 比如我要维持一个单态instance, 此单态instance是有状态的, 因为Application需要随时通过此单态instance读取或者修改某变量(比如修改或读取此单态中的一个map)。 难道只能把状态持久化? 再次强调, 是分布式应用(EJB)。 |
|
返回顶楼 | |
发表时间:2008-07-15
qfs_v 写道 不要是试图使用双重检查来 解决这个问题。 在java与模式中作者讲得很明白了。 在多线程的程序中,只能尽量降低同步的几率来保证单例的唯一性。 下面这这样就就是基于上面的理由。 private static HashCodeDigest instance = null; private HashCodeDigest() { } private static synchronized void syncInit() { if (instance == null) { instance = new HashCodeDigest(); } } public static HashCodeDigest getInstance() { if (instance == null) { syncInit(); } return instance; } 而这样做你是完全依赖于双重检查。 private static Singleton INSTANCE; public static Singleton getInstance(){ if(INSTANCE==null){ synchronized(Singelton.class){ //Double checking if(INSTANCE==null){ INSTANCE=new Singleton(); } } } } 我已经说的很清楚了,你这个就是变相的doublechecking。实际上没有本质区别。 你的问题在于,instance == null这个是不安全的。从前面的参考资料中可以得知,instance = new HashCodeDigest();这句话可能会这样执行: 1.给instance赋值(此时不是null了!!!) 2.调用构造器。(此时才初始化,而在前一步就通过检查了,这就是问题所在)。 |
|
返回顶楼 | |
发表时间:2008-07-15
Lucas Lee 写道 weiqingfei 写道 private static int hasInitialized=0;
private static Singleton INSTANCE; public static synchronized Singleton getInstance(){ if(hasInitialized==0){ synchronized(Singelton.class){ //Double checking if(hasInitialized==0){ INSTANCE=new Singleton(); hasInitialized=1; } } } } 谢谢提醒,我已经修改了,笔误。 我个人觉得还是不要把synchronized放在方法头, 这样子每次调用把个方法都要先锁一下感觉很别扭 |
|
返回顶楼 | |
发表时间:2008-07-15
还在讨论synchronized?第二页buaawhl 说的那个Initialization on Demand Holder (IODH),不是非常好的解决方案么?
比“饿汉式”更充分的lazy,比“双重检查”或“懒汉式(同步)”性能更好,代码也简捷。 |
|
返回顶楼 | |