单例模式的实现方式
1、只适用于单线程的环境
将构造函数私有化以禁止他人创建实例,定义一个静态私有的实例,当需要实例的时候,从中获取或创建(懒汉模式),是线程不安全的
public class Singleton1 { private Singleton1(){}; private static Singleton1 instance=null; public static Singleton1 getInstance(){ if(instance==null){ instance=new Singleton1(); } return instance; } }
2、能在多线程下工作但效率很低
在第一种情况中,如果两个线程同时判断instance是否为null,并且instance没有被创建,那么两个线程都会创建一个实例,就不再满足单例模式了。
public class Singleton2 { private Singleton2(){}; private static Singleton2 instance=null; public static synchronized Singleton2 getInstance(){ if(instance==null){ instance=new Singleton2(); } return instance; } }
3、饿汉模式
当类进行加载的时候,就实现实例化,可以避免多线程,其会过早创建一个实例,从而降低了内存的使用效率。public class Singleton3 { private Singleton3(){}; private static Singleton3 instance=new Singleton3(); public static Singleton3 getInstance(){ return instance; } }
也可以将实例化放在静态代码块中实现public class Singleton4 { private Singleton4(){}; private static Singleton4 instance=null; static{ instance=new Singleton4(); } public static Singleton4 getInstance(){ return instance; } }
4、双重检查锁定
public class Singleton5 { private Singleton5(){}; private volatile static Singleton5 instance=null; public static Singleton5 getInstance(){ if(instance==null){ synchronized(Singleton5.class){ if(instance==null){ instance=new Singleton5(); } } } return instance; } }
5、使用静态内部类
public class Singleton6 { private Singleton6(){}; private static final Singleton6 getInstance(){ return Singleton6Holder.INSTANCE; } private static class Singleton6Holder{ private static final Singleton6 INSTANCE=new Singleton6(); } }
定义了一个私有类型的内部类,当Singleton6被加载的时候,并不会直接实例化,只有当调用getInstance的方法时,才会实例化,实现了懒加载。