锁定老帖子 主题:对于单例模式的一点想法
精华帖 (1) :: 良好帖 (9) :: 新手帖 (11) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2008-07-07
public static SysRoleDAO getInstance() { if (sysRole == null) { synchronized (SysRoleDAO.class) { if (sysRole == null) { SysRoleDAO _sysRole = new SysRoleDAO(); sysRole = _sysRole; } } } return sysRole; } 试试这样 |
|
返回顶楼 | |
发表时间:2008-07-07
icewubin 写道 但是 public static final Singleton INSTANCE=new Singleton(); 这种模式的话,对这个类的任何访问都会触发,比如这个类有什么全局常量的访问,也会触发初始化,但是此时根本不需要初始化。 你这种说法不知道有什么证据? 我以前也和你一样,想当然这样认为“对这个类的任何访问都会触发,比如这个类有什么全局常量的访问,也会触发初始化”,但我做了个小实验,SUN JDK1.6下(JDK1.5一样): package test; public class Singleton { public static final String NAME = "test"; private static final Singleton INSTANCE = new Singleton(); private Singleton() { System.out.println("Invoke constructor."); } public static Singleton getInstance() { return INSTANCE; } } package test; public class Test1 { public static void main(String[] args) throws Exception { System.out.println(Singleton.NAME); System.out.println("-------------------"); Singleton.printString("Test static method."); } } 执行结果如下: test ------------------- Invoke constructor. Test static method. 说明调用Singleton.NAME常量是不会触发此类其他静态变量的初始化的,(即单例也不会被初始化)。 调用静态方法则会。 |
|
返回顶楼 | |
发表时间:2008-07-07
Lucas Lee 写道 你这种说法不知道有什么证据?
我以前也和你一样,想当然这样认为“对这个类的任何访问都会触发,比如这个类有什么全局常量的访问,也会触发初始化”,但我做了个小实验,SUN JDK1.6下(JDK1.5一样): package test; public class Singleton { public static final String NAME = "test"; private static final Singleton INSTANCE = new Singleton(); private Singleton() { System.out.println("Invoke constructor."); } public static Singleton getInstance() { return INSTANCE; } } package test; public class Test1 { public static void main(String[] args) throws Exception { System.out.println(Singleton.NAME); System.out.println("-------------------"); Singleton.printString("Test static method."); } } 执行结果如下: test ------------------- Invoke constructor. Test static method. 说明调用Singleton.NAME常量是不会触发此类其他静态变量的初始化的,(即单例也不会被初始化)。 调用静态方法则会。 static final会直接编译成常量,也就是Test1中的Single.NAME其实是直接初始化成常量,并没有调用到Singleton。看看这个帖子 http://www.iteye.com/topic/211937 |
|
返回顶楼 | |
发表时间:2008-07-08
lt0604 写道 单例在分布式应用中应该特别注意!
分布式应用中,单例干脆就别用了,即使用了也就是节省点内存的用途了。 |
|
返回顶楼 | |
发表时间:2008-07-08
多谢举出反例,不过即使如此,之前说的lazy的程度不一样还是成立的。
没想到JVM对static final的常量优化的如此彻底啊。 |
|
返回顶楼 | |
发表时间:2008-07-09
dennis_zane 写道 Lucas Lee 写道 你这种说法不知道有什么证据?
我以前也和你一样,想当然这样认为“对这个类的任何访问都会触发,比如这个类有什么全局常量的访问,也会触发初始化”,但我做了个小实验,SUN JDK1.6下(JDK1.5一样): package test; public class Singleton { public static final String NAME = "test"; private static final Singleton INSTANCE = new Singleton(); private Singleton() { System.out.println("Invoke constructor."); } public static Singleton getInstance() { return INSTANCE; } } package test; public class Test1 { public static void main(String[] args) throws Exception { System.out.println(Singleton.NAME); System.out.println("-------------------"); Singleton.printString("Test static method."); } } 执行结果如下: test ------------------- Invoke constructor. Test static method. 说明调用Singleton.NAME常量是不会触发此类其他静态变量的初始化的,(即单例也不会被初始化)。 调用静态方法则会。 static final会直接编译成常量,也就是Test1中的Single.NAME其实是直接初始化成常量,并没有调用到Singleton。看看这个帖子 http://www.iteye.com/topic/211937 是这样的,访问static final不属于主动调用。 |
|
返回顶楼 | |
发表时间:2008-07-10
再集群环境下怎么实现单例模式?
|
|
返回顶楼 | |
发表时间:2008-07-10
这样可能会好一点.
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; } |
|
返回顶楼 | |
发表时间:2008-07-10
lefish 写道 这样可能会好一点.
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; } 你这个就是我在最开始提到的普通的double-checking的做法,static synchronized method等效于synchonized(Singleton.class). 一样会有问题。 |
|
返回顶楼 | |
发表时间:2008-07-14
Lucas Lee 写道 slangmgh 写道 JVM 不保证代码INSTANCE=new Singleton() 一定在hasInitialized=1之前执行!!! 这个不会吧?你的证据呢? 我提到的out-of-order write只是对INSTANCE=new Singleton()范围而言。 连两条语句的顺序都无法保证,这个就难以想象了。。。 确实有这个可能的,如果两条语句的顺序改变不会影响执行结果,编译器有可能为某种优化对其进行顺序调整,我在《java concurrecy in practice》中看到的。 |
|
返回顶楼 | |