Java设计模式之单例模式

Android开发中都会用到的一种最简单的设计模式,尤其是当初的面试中经常被问到的一种设计模式:

第二篇:单例模式

当需要控制一个类的实例只能有一个,而且客户只能从一个全局访问点访问它时,可以选用单例模式。

单例模式有两种:饿汉式与懒汉式


一、饿汉式(饿汉式天生就是线程安全的,可以直接用于多线程而不会出现问题):

/**
 * 单例模式:
 * 饿汉式(饿汉式是线程安全的)
 * @author zhongyao
 */
public class Singleton {

	private static Singleton uniqueInstance = new Singleton();
	
	/**
	 * 私有构造方法
	 */
	private Singleton(){};
	
	public static Singleton getInstance(){
		
		return uniqueInstance;
	};
}


二、懒汉式(未经优化的懒汉式,存在线程安全问题):

/**
 * 懒汉式(线程不安全)
 * @author zhongyao
 *
 */
public class Singleton {
	
	private static Singleton singleton = null;
	
	private Singleton(){}
	
	public static Singleton getInstance(){
		
		if (singleton == null) {
			singleton = new Singleton();
		}
		
		return singleton;
	}
}

优化1、 在getInstance方法上加同步


/**
 * 单例模式:
 * 懒汉式(不加同步的懒汉式是线程不安全的)
 * @author zhongyao
 */
public class Singleton {
	private static Singleton uniqueInstance = null;
	/**
	 * 私有构造方法
	 */
	private Singleton(){};
	
	/**
	 * 虽然是线程安全的,但是会降低整个访问的速度
	 * @return
	 */
	public static synchronized Singleton getInstance(){
		
		if (uniqueInstance == null) {
			uniqueInstance = new Singleton();
		}
		return uniqueInstance;
	}
}

优化2、双重检查锁定:

/**
 * 懒汉式--双重检查锁定
 * @author zhongyao
 *
 */
public class Singleton {
	
	private static Singleton singleton = null;
	
	private Singleton(){}
	
	public static Singleton getInstanceFour(){
		
		if (singleton == null) {
			synchronized(Singleton.class){
				if (singleton == null) {
					singleton = new Singleton();
				}
			}
		}
		
		return singleton;
		
	}
}


优化3、静态内部类:

public class Singleton {    
    private static class LazyHolder {    
       private static final Singleton INSTANCE = new Singleton();    
    }    
    private Singleton (){}    
    public static final Singleton getInstance() {    
       return LazyHolder.INSTANCE;    
    }    
} 

1、2、3这三种懒汉式优化实现区别

第1种,在方法调用上加了同步,虽然线程安全了,但是每次都要同步,会影响性能,毕竟99%的情况下是不需要同步的,

第2种,在getInstance中做了两次null检查,确保了只有第一次调用单例的时候才会做同步,这样也是线程安全的,同时避免了每次都同步的性能损耗

第3种,利用了classloader的机制来保证初始化instance时只有一个线程,所以也是线程安全的,同时没有性能损耗,所以一般我倾向于使用这一种。



你可能感兴趣的:(java,设计模式)