论坛首页 Java企业应用论坛

对于单例模式的一点想法

浏览 23650 次
精华帖 (1) :: 良好帖 (9) :: 新手帖 (11) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-07-14  
spiritfrog 写道
这贴为什么给新手帖这么多?
难道都理解了?
ibm这篇http://www.ibm.com/developerworks/java/library/j-dcl.html
out-of-order writes往后,就很难看下去了。


因为这里的很多人很浮躁,以为这么简单的问题自己早就知道了。其实是错的。
0 请登录后投票
   发表时间: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.”
0 请登录后投票
   发表时间:2008-07-14  
单例模式用在java web问题多多。
0 请登录后投票
   发表时间:2008-07-14  
用Enum
0 请登录后投票
   发表时间: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;也优化的话 那就又有问题了
0 请登录后投票
   发表时间: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();   
      }   
    }   
  }   
} 

0 请登录后投票
   发表时间:2008-07-15  
既然在分布式应用中不赞成使用singleton。
那么如何在分布式应用中使用某种方式, 达到类似singleton的效果?
比如我要维持一个单态instance, 此单态instance是有状态的, 因为Application需要随时通过此单态instance读取或者修改某变量(比如修改或读取此单态中的一个map)。
难道只能把状态持久化?
再次强调, 是分布式应用(EJB)。
0 请登录后投票
   发表时间: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.调用构造器。(此时才初始化,而在前一步就通过检查了,这就是问题所在)。
0 请登录后投票
   发表时间: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放在方法头, 这样子每次调用把个方法都要先锁一下感觉很别扭
0 请登录后投票
   发表时间:2008-07-15  
还在讨论synchronized?第二页buaawhl 说的那个Initialization on Demand Holder (IODH),不是非常好的解决方案么?
比“饿汉式”更充分的lazy,比“双重检查”或“懒汉式(同步)”性能更好,代码也简捷。
1 请登录后投票
论坛首页 Java企业应用版

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