设计模式--单例模式
1. 单例模式介绍
什么是单例模式
单例模式是为了保证一个类只有一个实例,作为唯一的入口。
为什么要使用单例模式
因为有的类只需要一个实例即可,不用过多的创建实例,从而节省内存开销,减少不必要的浪费
单例模式有几种类型
主要分为 饿汉式和懒汉式
特点
创建一个变量保存当前类的实例
私有化构造方法,不允许主动创建对象
开放一个静态方法去返回当前类的实例
2. 饿汉式介绍
饿汉式是指无论当前类是否被使用,在类加载的时候都有一个对象被创建等待使用。
代码实现
1 /** 2 * 单例模式--饿汉式 3 * @Author:Ldy 4 * @Date:2021/7/14 5 */ 6 public class Singleton1 { 7 8 private static Singleton1 singleton1 = new Singleton1(); 9 10 private Singleton1(){} 11 12 public static Singleton1 getInstance(){ 13 return singleton1; 14 } 15 }
这种方式比较常用,容易实现,但是容易产生垃圾对象
多线程环境是否安全:安全
优点:没有加锁机制,执行效率高
缺点:在类加载时就创建了对象,浪费内存
3. 懒汉式介绍
懒汉式介绍是指只有在使用当前类时才去判断对象是否被创建,如果被创建则直接返回,反之则创建对象再返回。
这里主要介绍懒汉式中的 双重检查锁模式(DCL)
代码实现
1 /** 2 * 懒汉式 -- 双重检查锁模式(DCL) 3 */ 4 public class Singleton2 { 5 6 //volatile关键字的作用就是 为了解决以为重排序而导致读取不到完整的对象 7 private volatile static Singleton2 singleton2 = null; 8 9 private Singleton2(){} 10 11 public static Singleton2 getSingleton2Instance() { 12 // a 13 if(singleton2 == null){ 14 //JVN优化机制,先分配内存 再初始化 15 synchronized (Singleton2.class){ 16 if(singleton2 == null){ 17 singleton2 = new Singleton2(); // b 18 //1. new ---> 申请内存空间 19 //2. 完成属性的初始化(赋值) 20 //3. 将对象内存地址交给变量singleton2来保存 21 //存在的问题:假设此处有两个线程 a b, 此时b线程已经进入到b处,进行new Singleton2(),但是由于jvm优化机制,new一个对象其实 22 //分为三步,需要第三步执行后 singleton2才不为空,由于jvm的重排序,第二步和第三步顺序不一定,假设先执行了第三步,虽然singleton2不为空,但是属性的初始化未完成,此时时间片用完了。到a线程执行 a线程判断singleton2不为空 后续直接使用该对象调用方法,那么结果就是报错。 23 24 //如何解决上诉问题:将singleton2变量加上volatile 25 } 26 } 27 } 28 return singleton2; 29 } 30 31 }
这种双重锁模式可以在多线程环境下安全运行而且还能保持高性能。实现起来较难
对应点的解释都在代码的注释中。
本文来自博客园,作者:EchoLv,转载请注明原文链接:https://www.cnblogs.com/lvdeyinBlog/p/15010772.html

浙公网安备 33010602011771号