咱们经过单例模式能够保证系统中一个类只有一个实例并且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。若是但愿在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。安全
public class Singleton { private static final Singleton instance = new Singleton(); private Singleton(){ } public Singleton getSingleton(){ return instance; } }
该类的构造方法被private修饰,外部访问者只能经过getSingleton方法得到实例,而不能本身再建立实例,能够保证系统中只有一个实例,不足之处在于,该类在被加载时就实例化了一个对象,而无论其将在什么时间用到,所以咱们要考虑延迟等到真正须要时建立实例,请看下面的第二种方法:spa
该实例有用户经过一个线程安全的方法去建立,以下所示:线程
public class Singleton { private static Singleton instance = null; private Singleton() { } public static synchronized Singleton getSingleton() { if (instance == null) { return new Singleton(); } else { return instance; } } }
这种方式经过一个线程安全的方法,来获得一个实例,但每一个线程获取该实例时都要访问线程同步的方法,申请对象锁、得到对象、释放所持有的对象锁,通过这一些列的操做后,其它线程才可以获得实例。实际上只须要在建立实例时须要线程安全,获得这个实例其实就不须要维护线程安全开销了,为此能够利用下面的方式:code
public class Singleton { private static volatile Singleton instance; private Singleton() { } public static Singleton getSingleton() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
咱们对instance变量用volatile关键字修饰,以确保一个线程更改为员变量后,其它线程可以看到更改后的变量,也就是专业术语中的“可见性”,同时,咱们对getSingleton方法进行了改进,当且仅当建立实例时才进行同步,去获取实例时并无同步,以减小获取实例时的开销。对象