首页 > 技术文章 > 设计模式(1)-单例模式

guan-li 2018-10-31 09:55 原文


定义

保证只能获取到一个对象实例,如某辆列车的余票数量.


示例


1.1 饿汉模式

public class SingletonDemo1 {
	//构造函数私有,保证不能外部new创建
	private SingletonDemo1(){
	}
	//静态变量singleton在类加载时被初始化,final保证不可以被重定向为null.
	private static final SingletonDemo1 singleton = new SingletonDemo1();
	
	//获取实例
	public static SingletonDemo1 getInstance(){
		return singleton;
	}
}

注:多数时候是否懒加载对性能影响不大,可以使用.


1.2 饿汉模式变种

public class SingletonDemo2 {
	//私有构造函数
	private SingletonDemo2(){	
	}
	
	private static final SingletonDemo2 singleton;
	
	//静态代码块中初始化,和demo1无区别
	static{
		singleton = new SingletonDemo2();
	}
	
	public static SingletonDemo2 getInstance(){
		return singleton;
	}
}

和1中并无区别.


1.3 懒汉模式

public class SingletonDemo3 {
	private SingletonDemo3(){
		
	}
	private static SingletonDemo3 singleton;
	
	//同步保证了线程安全,不会出现创建多个对象,但效率较低.
	public static synchronized SingletonDemo3 getInstance(){
		if(singleton == null){
			singleton = new SingletonDemo3();
		}
		return singleton;
	}
}

注:实现了懒加载,但每次校验是否为空都要进入同步,效率低下.


1.4 懒汉模式变种:双重校验锁

public class SingletonDemo4 {
	private SingletonDemo4(){
		
	}
	
	//volatile关键字保证了变量在多个线程中修改的可见性
	private static volatile SingletonDemo4 singleton;
	
	public static SingletonDemo4 getInstance(){
		//双重校验锁,在对象已经被初始化后,无需进入同步方法.效率较demo3高.
		if(singleton == null){
			synchronized (SingletonDemo4.class) {
				if(singleton == null){
					singleton = new SingletonDemo4();
				}
			}
		}
		return singleton;
	}
}

注:只在第一次判断实例为空时,才进入第二次同步判断,效率较3中高.
注:volatile修饰变量时,保证了变量在一个线程中被修改后,在其他线程中的可见性,但不能保证变量操作的原子性.


1.5 匿名内部类

public class SingletonDemo5 {
	private SingletonDemo5(){
		
	}
	
	//在SingletonDemo5被加载时,SingletonInstance并未被加载
	private static class SingletonInstance{
		private static final SingletonDemo5 singleton = new SingletonDemo5();
	}
	
	public static SingletonDemo5 getInstance(){
		return SingletonInstance.singleton;
	}
}

注:另一种懒汉模式的实现.


1.6 枚举

public enum SingletonDemo6 {
	INSTANCE;
	
	public void doSomething(){
	}
}

线程安全,清晰简洁,推荐使用.


推荐阅读