当前位置:首页 > 开发 > 编程语言 > 编程 > 正文

不同的单例模式

发表于: 2012-03-16   作者:dongisland   来源:转载   浏览次数:
摘要: 一个简简单单的singleton经常看到引来很多争论。 只要类里面没得其它的static属性或方法,基本不需要考虑lazy load和thread safe,因为java字节码本来就是延时加载的,下面实现就行了。 public class Singleton { public static final Singleton so = new Singleton();
一个简简单单的singleton经常看到引来很多争论。
只要类里面没得其它的static属性或方法,基本不需要考虑lazy load和thread safe,因为java字节码本来就是延时加载的,下面实现就行了。
public class Singleton { 
    public static final Singleton so = new Singleton(); 
    private Singleton(){} 
} 

或者
public class Singleton { 
    private static Singleton so = new Singleton(); 
    private Singleton(){} 
    public static Singleton getInstance {return so;} 
} 

如果class Singleton里面有其它static属性或方法(这种情况几乎没有或者可以避免),这才考虑需不需要延时加载singleton对象,如果这些情况你都遇上了又确实不能忍受提前实例化。那就用holder class或double check(可以参考effective java(2e)中的item 71)。


下面是一个对单例的例子,有4中形式,转自一个回复,感觉好,自己就记录下来了,留给别人学习:
/**
 * @author lee
 * @date Mar 5, 201210:09:12 AM
 * @version V1.0
 * @todo 单例模式属于对象创建型模式,其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点
 */
public class Singleton {
	private static Singleton instance;
	private static Singleton instance1=new Singleton();
	private static Singleton instance2;
	private static Singleton instance3;
	private volatile static Singleton instance4;
	//私有构造方法,避免外部创建实例
	private Singleton(){
	}
	//懒汉式单例>当需要的时候,并且发现没有实例的时候,才去初始化. 多线程下这种单例模式是起不到效果的
	public static Singleton getInstance(){
		if(instance==null){
			threadSleep();
			instance=new Singleton();
		}
		return instance;
	}
	//饿汉式单例>管你需要不需要,反正我是饿了,类加载的时候就已经初始化,没有起到延迟加载的效果
	public static Singleton getInstance1(){
		return instance1;
	}
	//对懒汉式进行同步,牺牲了性能,同步的原则应该是尽量对代码块同步,不要对整个方法同步
	public static synchronized Singleton getInstance2(){
		if(instance2==null){
			threadSleep();
			instance2=new Singleton();
		}
		return instance2;
	}
	//双重检查加锁DCL(double checking lock),只在第一次调用getInstance()时才要同步,提高性能
	public static Singleton getInstance3(){
		if(instance3==null){
			threadSleep();
			synchronized (Singleton.class) {
				if(instance3==null){
					instance3=new Singleton();
				}
			}
		}
		return instance3;
	}
	
	public static Singleton getInstance4(){
		if(instance4==null){
			threadSleep();
			synchronized (Singleton.class) {
				if(instance4==null){
					instance4=new Singleton();
				}
			}
		}
		return instance4;
	}
	//让当前线程休眠1秒,模拟多个线程同时访问instance==null之后的临界情况
	public static void threadSleep(){
		try {
			System.out.println("当前线程休眠1秒!");
			Thread.currentThread().sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}


上面几种是常见的单例写法,下面分别弄几个线程测试一下,
public class ThreadTest extends Thread {
	
	@Override
	public void run() {
		Singleton s=Singleton.getInstance();
		System.out.println(s.toString());
		
		/*Singleton s1=Singleton.getInstance1();
		System.out.println(s1.toString());*/
		
		/*Singleton s2=Singleton.getInstance2();
		System.out.println(s2.toString());*/
		
		/*Singleton s3=Singleton.getInstance3();
		System.out.println(s3.toString());*/
	}
	public static void main(String[] args) {	
		for(int i=0;i<3;i++){
			ThreadTest test=new ThreadTest();
			test.start();
		}		
	}
}


把RUN方法里的注释,去掉,一次执行一个方法,发现除了第一个在多线程环境下不能实现真正的单例,其他的方法都是可以的。。。

网上有说DCL方法在JAVA中也不能实现真正的单例,不过,这测试结果好像也是可以的。
对单例的讨论过多,现在就到这吧,还是应用上的才是王道。

不同的单例模式

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
保证一个类只有一个实例,并提供一个访问它的全局访问点。 类图: 代码: template<typename T&g
java设计模式中有一个模式叫单例模式,单例的意思就是该类只能产生一个实例,平时我们定义类可以随
原文地址:http://www.cnblogs.com/Ray-xujianguo/p/3396884.html 在讲单例模式之前,我想先试讲一
在讲单例模式之前,我想先试讲一个例子,在什么程序中,我们都需要读取property配置文件,通过Java
单例模式 Singletonn Pattern Ensure a class has only one instance, and provide a global point
一. 单例模式 整理自 《java与模式》阎宏编著 1.意图: 确保某个类只有一个实例,并且为该类提供一
单例模式确保一个类只有一个实例,自行提供这个实例并向整个系统提供这个实例。 特点: 1,一个类只
首先来明确一个问题,那就是在某些情况下,有些对象,我们只需要一个就可以了, 比如,一台计算机上
一. 单例模式 整理自 《java与模式》阎宏编著 1.意图: 确保某个类只有一个实例,并且为该类提供一
一、 单例(Singleton)模式 单例模式的特点: • 单例类只能有一个实例。 • 单例类必须自己创建自
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号