单例设计模式
必须满足以下条件:
1、某个类只能有一个实例
构造器私有化
2、必须自行创建这个实例
静态变量来保存这个唯一的实例
3、必须自行向整个系统提供这个实例
对外提供获取该实例对象的方式:1.直接暴露2.静态变量的get方法获取
几种常见形式:
饿汉式:在类初始化时直接创建对象,不存在线程安全问题,不管你是否需要都会去创建
1、直接实例化饿汉式(简洁直观)
public class Singleton1 { public static final Singleton1 INSTANCE = new Singleton1(); private Singleton1(){ } }
2、枚举式(最简洁)
public enum Singleton2 { INSTANCE }
3、静态代码块饿汉式(适合复杂实例化)
public class Singleton3 { public static final Singleton3 INSTANCE; static { INSTANCE = new Singleton3(); } private Singleton3(){ } }
懒汉式:延迟创建这个实例对象
1、线程不安全(适用于单线程)
public class Singleton4 { private static Singleton4 instance; private Singleton4(){ } public static Singleton4 getInstance(){ if(instance == null){ instance = new Singleton4(); } return instance; } }
2、线程安全(适用于多线程)
public class Singleton5 { private static Singleton5 instance; private Singleton5() { } public static Singleton5 getInstance() { if (instance == null) { synchronized (Singleton5.class) { if (instance == null) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } instance = new Singleton5(); } } } return instance; } }
3、静态内部类形式(适用于多线程)
/* * 在内部类被加载和初始化时,才创建INSTANCE实例对象 * 静态内部类不会自动随着外部类的加载和初始化而初始化,它是要单独去加载和初始化的 * 因为实在内部类加载和初始化时创建的,因此是线程安全的 */ public class Singleton6 { private Singleton6() { } private static class Inner { private static final Singleton6 INSTANCE = new Singleton6(); } public static Singleton6 getInstance() { return Inner.INSTANCE; } }
总结:看需求选择使用饿汉式还是懒汉式,如果选择饿汉式的话枚举式是最简洁的,懒汉式则是静态内部类形式最简洁