单例模式
单例模式的优点:
由于单例模式只生成一个实例,减少了系统性能开销,当一个对象产生需要比较多资源时,如读取配置,产生其他依赖对象时,则可以通过启动时直接产生一个单例对象,然后永久的驻留在内存的方式解决
单例模式的实现:
有五中方式
1. 饿汉式
2. 懒汉式
3. 双重检测锁实现
4. 静态内部类实现
5. 枚举类型实现
下边对五中类型做详细笔记
饿汉式单例模式
饿汉式特点:线程安全,调用效率高,但是不能延时加载
缺点:如果只是加载类,而不调用类中的方法,则会造成资源浪费
饿汉式实现:
1. 在定义类中定义一个静态变量,然后创建类对象赋值给静态变量,
2. 构造器要私有化
3. 定义静态方法返回静态变量
代码:
public class SingletonDemo1 { //类初始化时,立即加载这个对象(没有延时加载的优势)。加载类时,天然的是线程安全的! private static SingletonDemo1 instance = new SingletonDemo1(); private SingletonDemo1(){ } //方法没有同步,调用效率高! public static SingletonDemo1 getInstance(){ return instance; } }
懒汉式单例模式
懒汉式特点:线程安全,调用效率不高,但是可以延时加载
缺点:资源利用率高了,但是每次调用getInstance()方法都要同步,并发效率低
懒汉式实现:
1. 在定义的类中定义一个私有的静态变量,不用赋值
2. 构造方法私有化
3. 对getInstance()方法加锁synchronized,方法中只创建一次对象,对静态变量赋一次值
代码:
public class SingletonDemo2 { //类初始化时,不初始化这个对象(延时加载,真正用的时候再创建)。 private static SingletonDemo2 instance; private SingletonDemo2(){ //私有化构造器 } //方法同步,调用效率低! public static synchronized SingletonDemo2 getInstance(){ if(instance==null){ instance = new SingletonDemo2(); } return instance; } }
双重检测锁实现单例
双重检测锁特点:实现了懒加载和调用效率高的特点
缺点:由于编译器优化原因和jvm底层内部模型原因,偶尔会出现问题,不建议使用
双重检测锁实现:
public class SingletonDemo3 { private static SingletonDemo3 instance = null; 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; } private SingletonDemo3() { } }
静态内部类实现单例
静态内部类特点:线程安全,调用效率高,懒加载
静态内部类单例实现:
1. 定义的类中定义一个静态内部类,静态内部类中定义一个静态常量,创建对象赋值给静态常量
2. 构造方法私有化
3. 定义getInstance()方法返回静态内部类中定义的静态常量
代码:
public class Singleto nDemo4 { private static class SingletonClassInstance { private static final SingletonDemo4 instance = new SingletonDemo4(); } private SingletonDemo4(){ } //方法没有同步,调用效率高! public static SingletonDemo4 getInstance(){ return SingletonClassInstance.instance; } }
枚举实现单例
枚举实现特点:线程安全,没有懒加载,调用效率高,实现简单,枚举本身就是单例模式,由JVM从根本上提供保障,避免通过反射和反序列化的漏洞
缺点:无延迟加载
枚举实现单例:
定义枚举类
在枚举类中定义一个元素
定义返回枚举中定义的元素
代码:
public enum SingletonDemo5 { //这个枚举元素,本身就是单例对象! INSTANCE; //添加自己需要的操作! public void singletonOperation(){ System.out.println("枚举实现单例模式"); } }
单例模式总结
主要:
饿汉式(线程安全,调用效率高,不能延时加载)
懒汉式(线程安全,调用效率不高,可以延时加载)
其他
双重检测锁式(由于jvm底层内部模型原型,偶尔会出现问题,不建议使用)
静态内部类(线程安全,调用效率高,可以延时加载)
枚举式(线程安全,调用效率高,不能延时加载,并且可以天然的防止反射和反序列化漏洞)
如何选用?
单例对象 占用资源少,不需要延时加载
枚举好于饿汉式
单例对象 占用资源大,需要延时加载
静态内部类好于懒汉式
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。