--- title: Java SE笔记: 单例模式 date: 2016-08-07 21:10:00 updated: 2016-08-07 21:10:00 description: "单例模式" categories: [个人笔记] tags: [Java, Java SE笔记, 代码块, 设计模式] --- > - 单例模式要领: > 1. `构造方法私有化` > 1. `对外提供一个公开的静态的获取当前类型对象的方法.` > 1. `提供一个当前类型的静态变量。` > - 单例模式分为两种: > - `饿汉式单例:在类加载阶段就创建了对象。` > - `懒汉式单例:用到对象的时候才会创建对象。` > - 为了解决什么问题? > 1. 为了保证JVM中某一个类型的java对象永远只有一个。 > 1. 为了节省内存的开销。 > - 缺点:单例模式的类无法被继承! ### 饿汉式(线程安全) ```java public class Singleton { private static Singleton uniqueInstance = new Singleton(); private Singleton() { } public static Singleton getUniqueInstance() { return uniqueInstance; } } ``` ### 懒汉式(线程不安全,延迟加载) ```java public class Singleton { private static Singleton uniqueInstance; private Singleton() { } public static Singleton getUniqueInstance() { if (uniqueInstance == null) { uniqueInstance = new Singleton(); } return uniqueInstance; } } ``` ### 懒汉式(线程安全,延迟加载) - 在方法上加锁,会影响性能 ```java public class Singleton { private static Singleton uniqueInstance; private Singleton() { } public static synchronized Singleton getUniqueInstance() { if (uniqueInstance == null) { uniqueInstance = new Singleton(); } return uniqueInstance; } } ``` ### 双重校验锁(线程安全,延迟加载) - 只对实例化的语句加锁 - 可能有多个线程进入外层if,所以在同步代码块里面再加一个锁防止多次实例化 - volatile关键字禁止JVM的指令重排 ```java public class Singleton { private volatile static Singleton uniqueInstance; private Singleton() { } public static Singleton getUniqueInstance() { if (uniqueInstance == null) { synchronized (Singleton.class) { if (uniqueInstance == null) { uniqueInstance = new Singleton(); } } } return uniqueInstance; } } ``` ### 静态内部类实现(线程安全,延迟加载) ```java public class Singleton { private Singleton() { } private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getUniqueInstance() { return SingletonHolder.INSTANCE; } } ``` ### 枚举实现(最佳实现) - 防止反射攻击 - 确保复杂序列化只创建一个实例 ```java public enum Singleton { uniqueInstance; } ```