设计模式-单例模式

一、饿汉式

在类被加载的时候就完成了创建,以后就使用这个实例。

  • 优点:在类加载的时候就完成了初始化,所以避免多线程之类的问题
  • 缺点:不管有没有使用这个类,这个类都会实例化出来,会造成内存浪费。
public class SingleTon {
    // 将构造方法私有化
    private SingleTon(){}

    // 创建好一个私有的实例
    private static SingleTon instance = new SingleTon();

    // 提供一个静态方法用于返回这个单例
    public static SingleTon getInstance() {
        return instance;
    }
}

二、懒汉式

这个类第一次被使用的时候才会去实例化对象,以后都是去使用这个对象

实现方式一

  • 优点:起到懒加载的作用
  • 缺点:会引发多线程的问题,从而创建出多个实例,即两个线程同时进入getInstance方法,第一个线程判断instance == null后,线程就挂起了。然后第二个判断 instance == null后,执行instance = new SingleTon(),并返回这个实例,然后第一个线程开始执行了,执行instance = new SingleTon(),此时就创建了两个实例了。所以使用的时候不推荐使用这个。
public class SingleTon {
    // 将构造方法私有化
    private SingleTon(){}

    // 创建好一个私有的实例
    private static SingleTon instance = null;

    // 提供一个静态方法用于返回这个单例
    public static SingleTon getInstance() {
        if (instance == null) {
            instance = new SingleTon();
        }
        return instance;
    }
}

实现方式二

  • 优点:起到懒加载的作用。加了锁,不会出现线程问题。
  • 缺点:每个线程进来的时候都必须要先获取锁,效率太差
public class SingleTon {
    // 将构造方法私有化
    private SingleTon(){}

    // 创建好一个私有的实例
    private static volatile SingleTon instance = null;

    // 提供一个静态方法用于返回这个单例
    public static synchronized SingleTon getInstance() {
        if (instance == null) {
            instance = new SingleTon();
        }
        return instance;
    }
}

实现方式三

  • 优点:起到懒加载的作用,线程安全,效率较高。
    注意点:instance必须使用volatile修饰,作用是防止指令重排,不加这句可能使用的对象还没有初始化完成。
    推荐使用
public class SingleTon {
    // 将构造方法私有化
    private SingleTon(){}

    // 创建好一个私有的实例
    private static volatile SingleTon instance = null;

    // 提供一个静态方法用于返回这个单例
    public static SingleTon getInstance() {
        if (instance == null) {
            synchronized (SingleTon.class) {
                if (instance == null) {
                    instance = new SingleTon();
                }
            }
        }
        return instance;
    }
}

三、静态内部类

  • 静态内部类方式在 SingleTon 类(父类)被装载时,不会导致内部类被装载,也就不会立即实例化,属于懒加载类型。当调用 getInstance() 方法时,才会装载 SingleTonInstance 类,从而完成SingleTon 的实例化。
  • 类的静态属性只会在第一次加载类的时候初始化,所以在这里,JVM 帮我们保证了线程的安全,在类初始化时,别的线程无法进入。
  • 避免了线程不安全,利用静态内部类特点实现延迟加载,效率高。
public class SingleTon {
    // 将构造方法私有化
    private SingleTon(){}

    // 在内部类中创建一个对象的实例,当父类SingleTon加载时,内部类无需加载,起到懒加载的作用
    private static class SingleTonInstance {
        private static SingleTon instance = new SingleTon();
    }

    // 提供一个静态方法用于返回这个单例
    public static SingleTon getInstance() {
        return SingleTonInstance.instance;
    }
}

四、枚举类

当Java虚拟机第一次加载枚举类时,它会自动创建枚举类的所有实例,所以是线程安全的,可放心使用。

enum SingleTon {
	// 当只有一个对象时就是单例
    INSTANCE;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值