百天打卡计划第五天-七种单例设计模式的设计

饿汉式

package day0518;

/**
 * @author liw
 * @date 2020-07-01
 */
public final class Singleton {
    //实例变量
    private byte [] data = new byte[1024] ;
    
    //在定义实例变量的时候直接初始化
    private static Singleton instance = new Singleton();

    //私有构造
    private Singleton() {

    }
    
    public static Singleton getInstance(){
        return instance ;
    }
}

 饿汉式的关键在于instance 作为类变量并且直接得到了初始化,如果住的的使用了Singleton类难么instance实例将直接完成创建,包括其中的实例变量都会得到初始化,1k的空间的data会被同时创建。

懒汉式

package day0518;

/**
 * @author liw
 * @date 2020-07-01
 */
public final class Singleton {
    //实例变量
    private byte[] data = new byte[1024];

    //定义实例,但不直接初始化
    private static Singleton instance = null;

    //私有构造
    private Singleton() {

    }

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

 所谓懒汉式就是在使用实例的时候再去创建(用时创建)。但是多线程的情况下是懒汉式是线程不安全的。懒汉式可以保证实例的懒加载,但是无法保证实例的唯一。

懒汉式 + 同步方法

package day0518;

/**
 * @author liw
 * @date 2020-07-01
 */
public final class Singleton {
    //实例变量
    private byte[] data = new byte[1024];

    //定义实例,但不直接初始化
    private static Singleton instance = null;

    //私有构造
    private Singleton() {

    }
    //getInstance 方法加入同步控制
    public static synchronized Singleton getInstance() {

        if (null == instance) {
            instance = new Singleton();
        }

        return instance ;
    }
}

 采用懒汉式+数据同步的方式既满足了懒加载又能百分百的保证instance 实例的唯一性,但是synchronized 关键字天生的排他性导致getInstance 方法只能在同一时刻被一个线程访问,性能低下。

Double-Check

package day0518;

import java.net.Socket;
import java.sql.Connection;

/**
 * @author liw
 * @date 2020-07-01
 */
public final class Singleton {
    //实例变量
    private byte[] data = new byte[1024];

    //定义实例,但不直接初始化
    private static Singleton instance = null;

    Connection conn;
    Socket socket;

    //私有构造
    private Singleton() {
        //对conn和socket进行初始化
    }

    //getInstance 方法加入同步控制
    public static synchronized Singleton getInstance() {

        if (null == instance) {
            synchronized (Singleton.class) {
                if (null == instance) {
                    instance = new Singleton();
                }
            }
        }

        return instance;
    }
}

 很聪明的一个方式通过两次校验,第一次判断当instance 为null的时候进入同步代码块,避免每次都需要进入同步代码快;第二次校验instance 为空则为其创建实例。但是这种方式在多线程的情况下有可能会造成空指针异常。有可能在成员变量实例化conn 、socket的发生在instance实例化之后。

Volatile +Double-Check

只需要在Double-Check 的模式代码上加个volatile。

package day0518;

import java.net.Socket;
import java.sql.Connection;

/**
 * @author liw
 * @date 2020-07-01
 */
public final class Singleton {
    //实例变量
    private byte[] data = new byte[1024];

    //定义实例,但不直接初始化
    private static volatile Singleton instance = null;

    Connection conn;
    Socket socket;

    //私有构造
    private Singleton() {
        //对conn和socket进行初始化
    }

    //getInstance 方法加入同步控制
    public static synchronized Singleton getInstance() {

        if (null == instance) {
            synchronized (Singleton.class) {
                if (null == instance) {
                    instance = new Singleton();
                }
            }
        }

        return instance;
    }
}

Holder 方式

package day0518;

import java.net.Socket;
import java.sql.Connection;

/**
 * @author liw
 * @date 2020-07-01
 */
public final class Singleton {
    //实例变量
    private byte[] data = new byte[1024];

    //私有构造
    private Singleton() {

    }

    private static class Holder {
        private static Singleton instance = new Singleton();
    }

    //getInstance 方法加入同步控制
    public static synchronized Singleton getInstance() {
        return Holder.instance;
    }
}

 Holder方式完全是借助了类的加载的特点。
在Singleton 类中并没有instance 的静态成员,而是将其放到了静态内部类Holder中,因此在Singleton 类的初始化过程中比不过不不会创建Singleton 的实例,Holder 类中定义了Singleton 的静态变量,并且直接进行了实例化,当Holder 被主动使用的时候则会创建Singleton 的实例,Singleton 实例的创建过程在java程序编译时期收集到()方法中,该方法又是同步方法,可以保证内存的可见性、jvm指令的顺序性和原子性。Holder方式的单例是最好的设计之一,也是目前使用比较广的设计。

枚举方式

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个双鱼座的测开

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值