专栏首页爱敲代码的猫java设计模式(2)-单例设计模式

java设计模式(2)-单例设计模式

上一篇推文写了工厂方法模式,包括简单工厂模式、多工厂模式、静态工厂模式、抽象工厂模式,这篇推文记录一下单例设计模式

单例设计模式

在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在。这样的模式有几个好处:某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销。省去了new操作符,降低了系统内存的使用频率,减轻GC压力。有些类如交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了。所以只有使用单例模式,才能保证核心交易服务器独立控制整个流程。

饿汗式

先创建实例,用静态方法调用优点:实现起来简单,没有多线程同步问题。

缺点:当类Singleton被加载的时候,会初始化static的instance,静态变量被创建并分配内存空间,从这以后,这个static的instance对象便一直占着这段内存(即便你还没有用到这个实例),当类被卸载时,静态变量被摧毁,并释放所占有的内存,因此在某些特定条件下会耗费内存。

public class SingleTon {

    //在类的内部创建一个类的实例
    private static SingleTon instance = new SingleTon();

    //私有构造方法,防止被实例化
    private SingleTon() {
    }

    //如果该对象被用于序列化,可以保证对象在序列化前后保持一致
    public Object readResolve() {
        return instance;
    }

    //私有化此对象,通过公共的方法来调用,此公共方法只能用类来条用(static修饰),同时类的实例也应为static
    public static SingleTon getInstance(){
        return instance;
    }
}

class Test{

    public static void main (String[] args){
        SingleTon s1 = SingleTon.getInstance();
        SingleTon s2 = SingleTon.getInstance();
        System.out.println(s1 == s2); //true
    }
}

在静态方法创建实例并直接调用如果不是线程同步,在多线程环境下,可能线程1正在创建单例时,线程2判断单例instance为空,就会创建多个实例优点:实现起来比较简单,当类Singleton被加载的时候,静态变量static的instance未被创建并分配内存空间,当getInstance方法第一次被调用时,初始化instance变量,并分配内存,因此在某些特定条件下会节约了内存。

缺点:在多线程环境中,这种实现方法是完全错误的,根本不能保证单例的状态。

public class SingleTon {
    //在类的内部创建一个类的实例
    private static SingleTon instance = null;

    private SingleTon(){}

    public static SingleTon getInstance(){
        if(instance == null){
            instance = new SingleTon();
        }
        return instance;
    }

}

class Test{

    public static void main (String[] args){
        SingleTon s1 = SingleTon.getInstance();
        SingleTon s2 = SingleTon.getInstance();
        System.out.println(s1 == s2); //true
    }
}

懒汉式(线程安全)

优点:在多线程情形下,保证了“懒汉模式”的线程安全。

缺点:众所周知在多线程情形下,synchronized 方法通常效率低,显然这不是最佳的实现方案。例如SingleTon实例不为null的情况下,线程同步机制必须等待才能进入if块,而如果存在实例,完全可以跳过等待,直接返回,因为不用进入if块。

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

        return instance;
    }
}

懒汉式(DCL双检查锁机制,线程安全)

public class SingleTon{
    private SingleTon(){}

    private static SingleTon instance = null;
    public static  SingleTon getInstance(){
        // 第一次检查instance是否被实例化出来,如果没有则进入if块
        if(instance == null){
            synchronized (SingleTon.class) {
                // 某个线程取得了类锁,实例化对象前第二次检查instance是否已经被实例化出来,如果没有,才最终实例出对象
                if (instance == null) {
                    instance = new SingleTon();
                }
            }
        }

        return instance;
    }

}

总结

单例模式理解起来简单,但是具体实现起来还是有一定的难度。synchronized关键字锁定的是对象,在用的时候,一定要在恰当的地方使用(注意需要使用锁的对象和过程,可能有的时候并不是整个对象及整个过程都需要锁)

本文分享自微信公众号 - 爱敲代码的猫(aquanrun),作者:Leemus

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-03-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • java设计模式(15)-观察者模式

    观察者模式很好理解,类似于邮件订阅和RSS订阅,当我们浏览一些博客或wiki时,经常会看到RSS图标,就这的意思是,当你订阅了该文章,如果后续有更新,会及时通知...

    爱敲代码的猫
  • 让你快速了解LocalDate类的基本用法

    LocalDate是带有年,月,日的日期。为了构建LocalDate对象,可以使用now或of静态方法栗子如下:

    爱敲代码的猫
  • java设计模式(6)-装饰模式

    上一篇文章分享了适配器模式,这篇推文整理一下装饰模式,和代理模式非常相似,但是实现和应用的场景不一样

    爱敲代码的猫
  • 简洁的HTML5视频播放器UI特效开源库

    近期在做一个项目时,遇到了播放视频的问题,找了很多插件和方法,今天介绍的这个是比较认为简洁和功能强大的开源库,可以任意修改播放格式。

    用户5997198
  • iOS开发之定位

    在iOS开发中,定位是很多App都需要使用的功能。本文主要对iOS中的定位知识点进行介绍。本文代码环境为:Xcode 10.1 + Swift 4.2。

    YungFan
  • Java语言中:float数据类型在内存中是怎么存储的?

    ============================================================================= ja...

    黑泽君
  • RxJava之初体验

    RxJava – Reactive Extensions for the JVM – a library for composing asy...

    open
  • Java开发知识之Java控制语句

      不管任何语言都有控制语句 if else if else whie do while for .... 首先讲解的是java的复合语句

    IBinary
  • PE文件详解(八)

    本文转载自小甲鱼PE文件详解系列教程原文传送门 当应用程序需要调用DLL中的函数时,会由系统将DLL中的函数映射到程序的虚拟内存中,dll中本身没有自己的栈...

    Masimaro
  • java中驼峰命名和下划线命名互转方法(代码实现)

    黑泽君

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动