• 设计模式-单例模式(懒汉式)


    1. 概念

    • 保证一个类只有一个实例
    • 并为该实例提供一个全局唯一的访问节点

    2. 懒汉式-方式一

    2.1 代码示例(方式一)

    示例
    public class Singleton03 {
    
        /**
         * 构造器私有化
         */
        private Singleton03() {
    
        }
    
        /**
         * 成员变量
         */
        private static Singleton03 INSTANCE;
    
        /**
         * 对外提供公有的静态方法
         */
        public static Singleton03 getInstance() {
            // 用到才加载
            if (INSTANCE == null) {
                INSTANCE = new Singleton03();
            }
            return INSTANCE;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    public class SingletonTest03 {
        public static void main(String[] args) {
            Singleton03 instance = Singleton03.getInstance();
            Singleton03 instance1 = Singleton03.getInstance();
            System.out.println(instance == instance1);
            System.out.println("instance.hashCode= " + instance.hashCode());
            System.out.println("instance1.hashCode= " + instance1.hashCode());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2.2 优缺点(方式一)

    1. 起到了Lazy Loading的效果,但是只能在单线程下使用。
    2. 如果在多线程下,一个线程进入了if(singleton==null)判断语句块,还未来得及
      往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例。所以
      在多线程环境下不可使用这种方式。

    2.3 结论(方式一)

    • 线程不安全,在实际开发中,不要使用这种方式。

    3. 懒汉式-方式二

    3.1 代码示例(方式二)

    示例
    public class Singleton04 {
        /**
         * 构造器私有化
         */
        private Singleton04() {
    
        }
    
        /**
         * 成员变量
         */
        private static Singleton04 INSTANCE;
    
        /**
         * 对外提供公有的静态方法
         */
        public static synchronized Singleton04 getInstance() {
            // 加入同步代码,解决线程不安全问题
            if (INSTANCE == null) {
                INSTANCE = new Singleton04();
            }
            return INSTANCE;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    public class SingletonTest04 {
        public static void main(String[] args) {
            Singleton04 instance = Singleton04.getInstance();
            Singleton04 instance1 = Singleton04.getInstance();
            System.out.println(instance == instance1);
            System.out.println("instance.hashCode= " + instance.hashCode());
            System.out.println("instance1.hashCode= " + instance1.hashCode());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3.2 优缺点(方式二)

    1. 解决了线程不安全问题。
    2. 效率太低了,每个线程在想获得类的实例时候,执行getinstance()方法都要进行同步。而其实这个方法只执行一次实例化代码就够了,后面的想想获得该类实例,直接return就行了。方法进行同步效率太低。

    3.3 结论(方式二)

    • 线程安全,但效率太低,在实际开发中,不推荐使用这种方式。

    4. 懒汉式-方式三

    4.1 代码示例(方式三)

    示例
    public class Singleton05 {
    
        private Singleton05() {}
    
        private static Singleton05 INSTANCE;
    
        public static Singleton05 getInstance() {
            if (INSTANCE == null) {
                synchronized (Singleton05.class) {
                    INSTANCE = new Singleton05();
                }
            }
            return INSTANCE;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    public class SingletonTest05 {
        public static void main(String[] args) {
            Singleton05 instance = Singleton05.getInstance();
            Singleton05 instance1 = Singleton05.getInstance();
            System.out.println(instance == instance1);
            System.out.println("instance.hashCode= " + instance.hashCode());
            System.out.println("instance1.hashCode= " + instance1.hashCode());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4.2 优缺点(方式三)

    1. 这种方式,本意是想对第四种实现方式的改进,因为前面同步方法效率太低,改为同步产生实例化的的代码块。
    2. 但是这种同步并不能起到线程同步的作用。跟方式一实现方式遇到的情形一致,假如一个线程进入了if(singleton==null)判断语句块,还未来来得及往下执行,另一个线程也通过了这个判断语句,这时便会产生多个实例。

    4.3 结论(方式三)

    • 线程不安全,在实际开发中,不要使用这种方式

  • 相关阅读:
    2 files found with path ‘lib/armeabi-v7a/liblog.so‘ from inputs:
    (四)Windows网络模型之完成端口模型详解
    面试算法22:链表中环的入口节点(1)
    pointpillars训练的输出信息
    技术管理三级跳
    一篇文章,带你了解CodeTour与入门指导
    初步认识端口服务查询--netstat
    网络安全观察报告 攻击态势
    9月第1周榜单丨飞瓜数据B站UP主排行榜(哔哩哔哩平台)发布!
    二分搜索篇
  • 原文地址:https://blog.csdn.net/m0_51176516/article/details/137198740