zoukankan      html  css  js  c++  java
  • 东北话讲单例模式,附代码

    大家好,博主是个东北人哈尔滨那嘎达的,在实习中吧,感觉自己学习之路贼拉长,学习又没乐趣,感觉工作中的人都感觉我都东北话好玩儿,

    那我就用东北话来分享一些知识和学习成果,这样既进步又有趣,以下有什么不对的欢迎大家呲哒我。

    在我们写代码的时候总会遇到抛异常啥的,但是那玩意究竟咋用,往哪嘎达用,我就简简单单分享一下子。

    单例设计模式的7种写法

    咱们在面试中面试官总会问我们会什么设计模式,一般我们会说几种常见的常用的设计模式:工厂方法模式、单例模式、建造者模式、原型模式

    代理........一大堆

    其实说的多不如会的精几个,下面我说一下我对单例的了解,也欢迎大家指正

    首先我们知道单例分为懒汉和饿汉

    第一种(懒汉,线程不安全)不建议用:

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

    懒汉,一看我们就能知道字面意思很懒,人家调用getInstance才实例化,但是如果多线程就不安全了,当多个线程同时调用getInstance时候,可能两条线程同时判断是null

    那么就可能出两个或者两个以上的实例,就违背了单例的原则,那么我们怎么能让懒汉也安全呢?

    第二种(懒汉,线程安全)同步方法不建议用:

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

    我们可以看出我们加了synchronized同步方法来控制线程安全,当一条线程执行getInstance()其他线程被阻塞,所以保证一个时刻只有一个线程访问,

    但是带来致命缺点就是会效率太低了。

    第三种(饿汉,线程安全)

    //对象是方法被调用时,才初始化,也叫做对象的延时加载。称为:懒汉式。
    public
    class Singleton{ private static Singleton instance = new Singleton(); private Singleton () { } public static Singleton getInstance() { return instance; } }

    代码可以看出,讲构造函数私有化,并且在类中创建一个本类对象,在类中写一个方法获取到本类对象。

    优点:这种写法比较简单,就是在类装载的时候就完成实例化。避免了线程同步问题。

    缺点:在类装载的时候就完成实例化,没有达到懒加载的效果。如果从始至终从未使用过这个实例的话,则会造成内存的浪费。

    第四种静态代码块(饿汉,线程安全)

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

    这种方式和上面的方式其实类似,只不过将类实例化的过程放在了静态代码块中,也是在类装载的时候,

    就执行静态代码块中的代码,初始化类的实例。优缺点和上面是一样的。

    第五种双重检查(可以用)

    public class Singleton {
        private static volatile Singleton singleton;
        private Singleton() {}
        public static Singleton getInstance() {
            if (singleton == null) {
                synchronized (Singleton.class) {
                    if (singleton == null) {
                        singleton = new Singleton();
                    }
                }
            }
            return singleton;
        }
    }

    Double-Check概念对于多线程开发来说不会陌生,就像代码中一张,我们进行了两次if (singleton == null)检查,这样就可以保证线程安全了。有人问怎么保证安全的呢?其实我们实例化代码执行一次后,后面再次访问时,判断第一个if (singleton == null)的时候因为不是null,所以不用走同步的 synchronized (Singleton.class) 直接return实例化对象。就可以了

    所以这种方法线程安全;延迟加载;效率较高。

    第六种静态内部类(可以用)

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

    其实这种和饿汉式有点一样又不咋像,都是用类装载的机制来保证初始化实例时只有一个线程,但是饿汉式加载就实例化了,没有懒加载,这种静态内部类就是在类加载不回实例化

    需要实例的时候调用getInstance,然后为我们返回一个内部类实例的Singleton。

    忘记说第七种了,其实就是一种懒汉,像第二种同步方法,这种就同步代码块,都是效率低,不建议使用的。

    打卡2018/11/16   博主是个实习的小白,每天积累一点,欢迎大家指正评论,一起加油!

  • 相关阅读:
    Python:完全数
    Python:将 list 写入一个 txt 文件
    Python:对称数组
    Python:列表反转、切片
    Python:print输出间隔,换行
    Python:打印99乘法表
    Python:排序(sort / 冒泡排序)
    安装pipenv
    flex布局
    python正则表达式
  • 原文地址:https://www.cnblogs.com/zhaokexin/p/9968078.html
Copyright © 2011-2022 走看看