码迷,mamicode.com
首页 > 其他好文 > 详细

单例模式(Singleton Pattern)

时间:2015-03-17 21:55:20      阅读:125      评论:0      收藏:0      [点我收藏+]

标签:singleton



单例模式确保一个类只会有一个实例,而且会提供一个全局访问点,特别用于资源敏感的对象。在实现的时候要考虑多线程环境,就需要同步。在Singleton4实现中用双重检查加锁,减少同步粒度,从而只会在第一次(不超过两次)请求该实例的时候才会进行同步,在这里,之所以要Double Check的原因是:假设线程P1,P2都执行到了pointA处,此时P1获得对象锁,进入了同步块,然后发现此时uniqueInstance的确为空,所以构造一个实例,退出同步块,释放锁,而后P2获得锁进入同步区域, 在这时如果不再次判断uniqueInstance非空的话,会再次构建一个实例,从而不再单例。

代码如下:
package singleton;

//经典实现方式,但是在多线程环境下就会出问题,
//可能连个线程同时进入了uniqueInstance==null那条控制路径
public class Singleton {
	private static Singleton uniqueInstance;

	private Singleton() {
	} //

	public static Singleton getInstance() {
		if (uniqueInstance == null) { // 延迟实例化,懒汉式
			uniqueInstance = new Singleton();
		}
		return uniqueInstance;
	}
}

//对方法加锁,同步线程对其的调用
//但是只有第一次执行getInstance时,才真正需要同步,其他时候都是对性能的损耗
public class Singleton2 {
	private static Singleton2 uniqueInstance;

	private Singleton2() {
	}

	// 每次都需要同步
	public static synchronized Singleton2 getInstance() {
		if (uniqueInstance == null) {
			uniqueInstance = new Singleton2();
		}
		return uniqueInstance;
	}
}

//使用“急切”创建实例(饿汉式),JVM会在线程访问这个静态变量之前,一定先创建这个实例,所以线程安全。
//缺点是不是在需要的时候才创建实例
public class Singleton3 {
	private static  Singleton3 uniqueInstance = new Singleton3();

	private Singleton3() {
	}

	// 直接使用
	public static  Singleton3 getInstance() {
		return uniqueInstance;
	}
}

//利用双重检查加锁,在getInstance方法中减少使用同步,只有第一次会同步
public class Singleton4 {
	private static volatile Singleton4 uniqueInstance;

	private Singleton4() {
	}

	// 缩小同步范围
	public static synchronized Singleton4 getInstance() {
		if (uniqueInstance == null) {//pointA
			synchronized(Singleton4.class){
				if(uniqueInstance == null)//pointB
					uniqueInstance = new Singleton4();
			}
		}
		return uniqueInstance;
	}
}


JDK中的单例场景有:
(1)java.lang.Runtime 中的getRuntime();
public class Runtime {
    private static Runtime currentRuntime = new Runtime();

    public static Runtime getRuntime() {
        return currentRuntime;
    }

    /** Don't let anyone else instantiate this class */
    private Runtime() {}

    ..............
}



(2)java.awt.Desktop 中的getDesktop(); 
public class Desktop {

    private DesktopPeer peer;

    /**
     * Suppresses default constructor for noninstantiability.
     */
    private Desktop() {
        peer = Toolkit.getDefaultToolkit().createDesktopPeer(this);
    }
    public static synchronized Desktop getDesktop(){
        if (GraphicsEnvironment.isHeadless()) throw new HeadlessException();
        if (!Desktop.isDesktopSupported()) {
            throw new UnsupportedOperationException("Desktop API is not " +
                                                    "supported on the current platform");
        }

        sun.awt.AppContext context = sun.awt.AppContext.getAppContext();
        Desktop desktop = (Desktop)context.get(Desktop.class);

        if (desktop == null) {
            desktop = new Desktop();
            context.put(Desktop.class, desktop);
        }

        return desktop;
    }





单例模式(Singleton Pattern)

标签:singleton

原文地址:http://blog.csdn.net/vonzhoufz/article/details/44348201

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!