单例模式设计

目标:

1. 饿汉模式

2. 懒汉模式

3. 饿汉模式优化

目录

饿汉模式 

懒汉模式

懒汉模式优化


 

饿汉模式 

由名字我们就可以知道 "饿汉" 嘛,就比较急切,在类加载的时候就创建实例

1. 写一个类,在本类中构造实例,用static修饰,直接创建出来(提供一个现有的实例)

2. 在本类中写一个方法获取到上面的实例

3. 将这个类的构造方法设置为私有的,让外部不能 new 这个对象

//饿汉模式:直接 static 一个实例(线程安全)

//期望这个类只能有一个实例
public class Demo1 {

    //只构造一个实例
    private static Demo1 instance = new Demo1();

    //获取这个实例
    public static Demo1 getInstance() {
        return instance;
    }

    //把构造方法设置为私有 外部不能 new 这个类对象
    private Demo1(){}
}

懒汉模式

由名字我们就可以知道 "懒汉" 嘛,就比较从容~,它是等到有人调用的时候再创建实例

1. 写一个类,在本类中构造实例,用static修饰,赋值为空(等待有人调用)

2. 在本类中写一个方法获取到上面的实例

3. 将这个类的构造方法设置为私有的,让外部不能 new 这个对象

//懒汉模式:

//期望这个类只能有一个实例
public class Demo2 {
    private static Demo2 instance = null;

    //获取这个实例
    public static Demo2 getInstance() {
        if (instance == null) {
            instance = new Demo2();
        }
        return instance;
    }

    //把构造方法设置为私有 外部不能 new 这个类对象
    private Demo2(){}

}

懒汉模式优化

根据上面的 "懒汉模式" 和 "饿汉模式"。我们可以知道,懒汉模式,它只是负责读取,没有修改。而 " 饿汉模式 " 是既读取,也进行修改。所以来说, "懒汉模式" 是线程安全的, "饿汉模式" 是线程不安全的。

所以为了使 " 饿汉模式" 线程安全,我们做以下几步操作:

1. 进行加锁:怎么加呢???

我们应该给整个 if 语句进行加锁,防止两个线程同时调用的时候都为 null ,从而就实例化了两个。

//懒汉模式优化
public class Demo3 {

    private static volatile Demo3 instance = null;

    //获取这个实例
    public static Demo3 getInstance() {
        
            synchronized (Demo3.class) {
                if (instance == null) {
                    instance = new Demo3();
                }
            }
        
        return instance;
    }

    //把构造方法设置为私有 外部不能 new 这个类对象
    private Demo3(){}


}

2. 线程安全是解决了,但是呢?

我们会发现,后续我们每次调用 getInstance() 的时候,都必须进行加锁一次,我们也没必要每次都加锁(加锁其实也是很大的开销,可能会使好多线程阻塞等待,影响了效率),当不为 null 的时候,就不用加锁了,这样就迎刃而解了~~~

//懒汉模式优化
public class Demo3 {

    private static volatile Demo3 instance = null;

    //获取这个实例
    public static Demo3 getInstance() {
        if (instance == null) {
            synchronized (Demo3.class) {
                if (instance == null) {
                    instance = new Demo3();
                }
            }
        }
        return instance;
    }

    //把构造方法设置为私有 外部不能 new 这个类对象
    private Demo3(){}


}

你可能感兴趣的:(单例模式,java,开发语言)