作用
- 保证一个类只有一个对象,并且提供一个访问改实例的全局访问点
优点
- 在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)
- 避免对资源的多重占用(比如写文件操作)
何时使用
- 当您想控制实例数目,节省系统资源的时候
常见应用场景
- Windows的Task Menager
- windows的Recycle Bin(回收站)
- 项目中读取配置的类,每次只能new一个区读外部配置
- 网站的访问情况,比如统计人数
- 数据库连接池
实例
- 主要
饿汉式(线程安全,调用效率高,不能延时加载)
package xin.chen.create_type.singleton; /** * @Author: create_By: chenxin * @Data:Created in 2018/8/2 14:54 * @Version: * @Acton: 测试饿汉式(很饿,马上就弄吃的) */ public class SingletonDemo1 { /** 类初始化的时候就 立即加载这个类 */ private static SingletonDemo1 instance = new SingletonDemo1(); /** 私有化构造器,不让new */ private SingletonDemo1(){ } /** 提供一个静态的公共的调用实例的方法,没有同步,调用效率高 */ public static SingletonDemo1 getInstance(){ return instance; } }
懒汉式(线程安全,调用效率不高,可以延时加载)
package xin.chen.create_type.singleton; /** * @Author: create_By: chenxin * @Data:Created in 2018/8/2 14:54 * @Version: * @Acton: 测试懒汉式(很懒,需要的时候就弄池的) */ public class SingletonDemo2 { /** 类初始化的时候就 不初始化这个对象 */ private static SingletonDemo2 instance; /** 私有化构造器,不让new */ private SingletonDemo2(){ } /** 提供一个静态的公共的调用实例的方法,有同步,调用效率低 */ public static synchronized SingletonDemo2 getInstance(){ if(instance == null){ instance = new SingletonDemo2(); } return instance; } }
- 其他
双重检测锁式(由于JVM底层内部模式原因,偶尔会出现问题,不建议使用)
package xin.chen.create_type.singleton; /** * @Author: create_By: chenxin * @Data:Created in 2018/8/2 14:54 * @Version: * @Acton: 测试双重检测锁 懒加载 */ public class SingletonDemo3 { /** 类初始化的时候就 不初始化这个对象 */ private static SingletonDemo3 instance; /** 私有化构造器,不让new */ private SingletonDemo3(){ } /** 提供一个静态的公共的调用实例的方法,第一次调用同步,调用效率高,懒汉式 */ public static SingletonDemo3 getInstance(){ if(instance == null){ SingletonDemo3 sc; synchronized (SingletonDemo3.class){ sc = instance; } if (sc == null) { synchronized (SingletonDemo3.class){ if(sc == null){ sc = new SingletonDemo3(); } } instance = sc; } } return instance; } }
静态内部式(线程安全,调用效率高,可以延时加载)
package xin.chen.create_type.singleton; /** * @Author: create_By: chenxin * @Data:Created in 2018/8/2 14:54 * @Version: * @Acton: 静态内部内 线程安全 调用效率高 延时加载 */ public class SingletonDemo4 { private static class SingletonClassInstance { private static final SingletonDemo4 instance = new SingletonDemo4(); }; /** 私有化构造器,不让new */ private SingletonDemo4(){ } /** 提供一个静态的公共的调用实例的方法 */ public static SingletonDemo4 getInstance(){ return SingletonClassInstance.instance; } }
枚举式(线程安全,调用效率高,不能延时加载
package xin.chen.create_type.singleton; /** * @Author: create_By: chenxin * @Data:Created in 2018/8/2 14:54 * @Version: * @Acton: 枚举 最好的一个,没有延时加载机制 无法被反射破解 */ public enum SingletonDemo5 { INSTANCE; public void singletonOperation(){ //其他操作 } }
附加:懒汉式(如何防止反射和序列化漏洞)
package xin.chen.create_type.singleton; import java.io.Serializable; /** * @Author: create_By: chenxin * @Data:Created in 2018/8/2 14:54 * @Version: * @Acton: 测试懒汉式(如何防止反射和序列化漏洞) */ public class SingletonDemo6 implements Serializable { /** 类初始化的时候就 不初始化这个对象 */ private static SingletonDemo6 instance; /** 私有化构造器,不让new */ private SingletonDemo6(){ //通过抛异常防范反射 if(instance != null){ throw new RuntimeException(); } } /** 提供一个静态的公共的调用实例的方法,有同步,调用效率低 */ public static synchronized SingletonDemo6 getInstance(){ if(instance == null){ instance = new SingletonDemo6(); } return instance; } //破解反序列化 private Object readResolve(){ return instance; } }
创建三步曲
- 私有的静态创建实例
- 私有的构造器
- 向外部提供一个共有的静态的获取实例的方法