单例模式(Singleton Pattern)

定义

单例模式(Singleton Pattern)是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点(静态方法)。单例模式属于创建型模式。常见的ServletContext、ServletContextConfig、ApplicationContext以及数据库的连接池等都是以单例形式存在的。

常见的单例模式

  • 饿汉式
    饿汉式单例是在类加载的时候就立即初始化,并且创建单例对象。绝对线程安全,在线程还没出现以前就是实例化了,不会存在访问安全问题。
    优点:没有加任何的锁、执行效率比较高,在用户体验上来说,比懒汉式更好。
    缺点:类加载的时候就初始化,不管用与不用都占着空间,浪费了内存空间。

代码示例如下:

public class HungrySingleton { 
	private static final HungrySingleton hungrySingleton = new HungrySingleton();
	private HungrySingleton(){}
	//全局访问点
	public static HungrySingleton getInstance(){ 
    	return hungrySingleton; 
	}
} 

还可以利用静态代码块来实现:

public class HungryStaticSingleton { 
	private static final HungryStaticSingleton hungrySingleton;
	static { 
		hungrySingleton = new HungryStaticSingleton(); 
	} 
	private HungryStaticSingleton(){} 
	public static HungryStaticSingleton getInstance(){ 
		return hungrySingleton; 
	}
} 
  • 懒汉式
    懒汉式单例是在被外部类调用时才创建实例。
    示例如下:
public class LazySimpleSingleton { 
	private LazySimpleSingleton(){} 
	private static LazySimpleSingleton lazy = null; 
	public static LazySimpleSingleton getInstance(){ 
		if(lazy == null){ 
			lazy = new LazySimpleSingleton(); 
		} 
	return lazy; 
	} 
} 

不过,上面的单例存在线程安全隐患,为了保证线程安全,我们可以采用双重检查锁的机制:

public class LazyDoubleCheckSingleton { 
	private volatile static LazyDoubleCheckSingleton lazy = null;
	private LazyDoubleCheckSingleton(){} 
	public static LazyDoubleCheckSingleton getInstance(){ 
		if(lazy == null){ 
			synchronized (LazyDoubleCheckSingleton.class){ 		
				if(lazy == null){ 
					lazy = new LazyDoubleCheckSingleton();
				} 
			}
		} 
		return lazy; 
	}
} 

但是,用到synchronized关键字,总归是要上锁,对程序性能还是存在一定影响的。我们可以从类初始化角度来考虑,采用静态内部类的方式:

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

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