单例模式实现的懒汉模式、饿汉模式

本文详细介绍了单例模式中的饿汉模式和懒汉模式,并通过示例代码展示了如何实现线程安全的懒汉模式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

饿汉模式

由于单例模式中,一个类只能拥有一个实例对象,所以需要将类构造方法封装,防止类被创建多个实例对象,但是在使用该类时必须要得到该类的实例对象,因此我们得创建一个获取该唯一实例对象的方法getInstance。

而对于该类的实例对象,在类中我们可以使用属于类的成员变量来保存(即static成员变量)。

//单例模式 - 饿汉模式
class HungrySingleton {
    //1.使用一个变量来保存该类唯一的实例,因为单例模式在一个程序中只能拥有一个实例,由于static成员只有一份,我们可以使用static变量来保存
    private static final HungrySingleton instance = new HungrySingleton();

    //2.封装构造方法,防止该类被实例出新的对象
    private HungrySingleton() {}

    //3.获取该类的唯一实例对象
    public HungrySingleton getInstance() {
        return instance;
    }
}

懒汉模式

线程不安全

懒汉模式相比于饿汉模式,区别就是实例对象创建时机不同,懒汉模式需要等到第一次使用时才创建实例对象,所以仅仅只需要修改获取对象的方法即可。

不考虑多线程情况,懒汉模式实现代码如下:

//单例模式 - 懒汉模式
class SlackerSingleton {
    //1.使用一个变量来保存该类唯一的实例,因为单例模式在一个程序中只能拥有一个实例,由于static成员只有一份,我们可以使用static变量来保存
    //懒汉单例模式是在使用的时候创建对象,因此初始时对象不应该被创建
    private static SlackerSingleton instance;

    //2.封装构造方法,防止该类被实例出新的对象
    private SlackerSingleton() {}

    //3.获取该类的唯一对象,如果没有就创建
    public SlackerSingleton getInstance() {
        if (instance == null) {
            instance = new SlackerSingleton();
        }
        return instance;
    }
}

线程安全

public class LazyHungry {
    private LazyHungry(){
        System.out.println(Thread.currentThread().getName()+"ok");
    }

    //对象用的时候才去加载
    private static LazyHungry lazyHungry;

    public static LazyHungry getInstance()
    {
        //需要加锁
        if(lazyHungry==null){
            synchronized (LazyHungry.class){
                if(lazyHungry==null){
                    lazyHungry=new LazyHungry();//不是原子性操作,可能会发生指令重排
                    /**
                     * 1、分配内存空间
                     * 2、执行构造方法,初始化对象
                     * 3、把这个对象指向这个空间
                     *
                     *  就有可能出现指令重排问题
                     *  比如执行的顺序是1 3 2 等
                     *  我们就可以添加volatile保证指令重排问题
                     */
                }
            }
        }
        return lazyHungry;
    }


    //多线程并发有问题
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            new Thread(()->{
                LazyHungry.getInstance();
            },String.valueOf(i)).start();
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值