单例模式指的是一个类只有一个实例化对象,懒汉模式是只有在使用的时候才去创建实例化对象。
//单例模式,构造方法必须是私有的,私有化保证了别的地方不会实例化。 //缺点是在类加载的时候就实例化了一次对象 public class Mgr01 { private static final Mgr01 mgr01=new Mgr01(); private Mgr01(){ } public static Mgr01 getInstance(){ if(mgr01==null){ return null; }else{ return mgr01; } } public static void main(String[] args) { Mgr01 a=Mgr01.getInstance(); Mgr01 b=Mgr01.getInstance(); System.out.println(a==b); } }
//懒加载。缺点是懒加载会引发出线程不安全的问题 //线程不安全问题可以使用加锁的方式解决,加锁使用的是double+check+lock //此处必须有volatile,因为在对象初始化的时候会存在指令重排的现象,这样对象会是一个不完整的对象。volatile会防止指令重排。 public class Mgr03 { private static volatile Mgr03 mgr03; private Mgr03(){ } public static Mgr03 getInstance(){ if(mgr03==null){ synchronized (Mgr03.class) { if(mgr03==null){ try { Thread.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } mgr03=new Mgr03(); } } } return mgr03; } public static void main(String[] args) { for (int i = 0; i <1000 ; i++) { new Thread(()->{ System.out.println(Mgr03.getInstance().hashCode()); }).start(); } } }
//完美的解决方案可以使用静态内部类的方式,不需要加锁 public class Mgr04 { private Mgr04(){ } public static class Mgr041{ private static final Mgr04 mgr04=new Mgr04(); } public static Mgr04 getInstance(){ return Mgr041.mgr04; } public static void main(String[] args) { for (int i = 0; i <1000 ; i++) { new Thread(()->{ System.out.println(Mgr04.getInstance().hashCode()); }).start(); } } }