东北话讲单例模式,附代码

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

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

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

单例设计模式的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   博主是个实习的小白,每天积累一点,欢迎大家指正评论,一起加油!

 

转载于:https://www.cnblogs.com/zhaokexin/p/9968078.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值