• 大话设计模式读书笔记(单例模式)


    人物:大鸟,小菜

    事件:小菜在点击一个小工具的图标时,每次点击都会创建一个窗体,但是小菜希望的是,第一次点击新建一个窗体,但是后面的每次点击都只会弹出以前创建的那个窗体,小菜很郁闷,于是大鸟让小菜借此学习单例模式。


    单例模式:

    1.简介单例模式,并讲述了单例模式的懒汉式

    2.介绍了单例模式的饿汉式

    单例模式(懒汉式)

    1.概念:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

    2.特点:单例模式只能有一个实例;单例类必须创建自己的唯一实例;单例类可以为其他类提供这一实例

    3.懒汉式基础代码实现:

    Singleton类,即单例类:

    public class Singleton {
        private static Singleton instance;
    
        private Singleton() {
        }
    
        public static Singleton getInstance() {
            if (instance == null) {
                instance = new Singleton();
            }
            return instance;
        }
    }

    客户端:

    @Slf4j
    public class SingletonClient {
        public static void main(String[] args) {
            Singleton s1 = Singleton.getInstance();
            Singleton s2 = Singleton.getInstance();
    
            if (s1 == s2) {
                log.info("两个对象是相同的实例");
            }
        }
    }

    输出结果:

    两个对象是相同的实例

    4.多线程下怎么保证单例模式线程安全,即加锁

    注意:在多线程中,可能多个线程同时访问Singleton类,为了避免创建多个实例,加锁如下:

    public class Singleton {
        private static Singleton instance;
        private static final Object lock = new Object();
    
        private Singleton() {
        }
    
        public static Singleton getInstance() {
            synchronized (lock) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
            return instance;
        }
    }

    小菜:那这样不是会每次都加锁么,可能没有创建实例也直接加锁了?

    大鸟:那还可以做如下改动,先判断实例是否为空,再看锁不锁

    5.实现双重锁定如下:

    public class Singleton {
        private static Singleton instance;
        private static final Object lock = new Object();
    
        private Singleton() {
        }
    
        public static Singleton getInstance() {
            if (instance == null) {
                synchronized (lock) {
                    if (instance == null) {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }

    6.静态内部类,保证线程安全由提高点性能:

    public class Singleton {
    
        private Singleton() {
        }
    
        private static class LazyHolder {
            private static final Singleton instance = new Singleton();
        }
    
        public static Singleton getInstance() {
            return LazyHolder.instance;
        }
    }

    问:为什么静态内部类是线程安全的?

    答:利用了类中静态变量的唯一性,而且不加锁性能会好很多

    单例模式(饿汉式)

    public class Singleton {
    
        private Singleton() {
        }
    
        private static final Singleton single = new Singleton();
    
        public static Singleton getInstance() {
            return single;
        }
    }

    问:为什么这种方式是线程安全的?

    答:在类创建的时候,也会创建类里面的静态对象,而静态对象一旦创建,又利用了静态变量的唯一性,和懒汉式的静态内部类有些相似

    问:那静态内部类和饿汉式有什么区别呢?

    答:静态内部类,需要时才加载类中的方法,又因为饿汉式里一开始就将静态变量加载,所以使用上的性能可能没有饿汉式的好

          饿汉式,第一次加载类时直接就将静态变量加载了,但是如果后面一直不使用,就会造成内存的浪费

  • 相关阅读:
    安装VMtools vim编辑器的使用 压缩包命令 Linux下的用户管理 (第三天)
    VM虚拟机安装 常用Linux命令 网卡配置 (第二天)
    数据库的交互模式 常用的dos命令 (第一天)
    Validate US Telephone Numbers FreeCodeCamp
    Arguments Optional FreeCodeCamp
    Everything Be True FreeCodeCamp
    Binary Agents FreeCodeCamp
    Steamroller FreeCodeCamp
    Drop it FreeCodeCamp
    Smallest Common Multiple FreeCodeCamp
  • 原文地址:https://www.cnblogs.com/wencheng9012/p/13442137.html
Copyright © 2020-2023  润新知