zoukankan      html  css  js  c++  java
  • 大话设计模式读书笔记(单例模式)

    人物:大鸟,小菜

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


    单例模式:

    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;
        }
    }

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

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

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

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

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

  • 相关阅读:
    CAS 认证
    最近邻规则分类(k-Nearest Neighbor )机器学习算法python实现
    scikit-learn决策树的python实现以及作图
    module object has no attribute dumps的解决方法
    最新Flume1.7 自定义 MongodbSink 结合TAILDIR Sources的使用
    数据探索中的贡献度分析
    python logging模块按天滚动简单程序
    Flume性能测试报告(翻译Flume官方wiki报告)
    python apsheduler cron 参数解析
    python pyspark入门篇
  • 原文地址:https://www.cnblogs.com/wencheng9012/p/13442137.html
Copyright © 2011-2022 走看看