单例模式java 个人简单理解

单例模式

单例模式是Java中最简单的设计模式,属于创建型模式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有的单个对象被创建。这个类提供了一种访问其唯一对象的方式,可直接访问,不需要实例化改类的对象。

核心就是 私有类构造器(保证只有在内部可以实例化),同时暴露对外的获取方法。

笔者认为,实现单例的方向主要分为两大类。
其一是通过多线程+锁的机制,确保同一时刻只有一个线程可以进行初始化操作
其二是利用classloader机制确保实例的唯一性。

多线程 + 锁:

这种情况下,单例又有两种模式,饿汉单例和懒汉单例。

**饿汉单例:**不管实例是否会被使用,在变量定义的时候,会被直接初始化。这样保证实例只有在类加载的时候会被初始化一次,以此实现单例。

class Singleton {
    private static Singleton singleton = new Singleton();
    private Singleton() {}
    public static Singleton getInstance() {
        return singleton;
    }
}

**懒汉单例:**懒加载机制(lazy loading),类似kotlin中的by lazy ,只有在需要的时候才会进行初始化。

class Singleton {
    private static Singleton singleton;
    private Singleton () {}
    public static Singleton getInstance() {
        if (singleton == null)
            singleton = new Singleton();
        return singleton;
    }
}

这种情况固然可以实现单例,但是在高并发的场景下,若有不同的线程同时访问getInstance方法,则可以new不止一次,造成不同的实例出现。接下来,我们对上诉Demo进行优化。

**优化方案一:**类上加锁

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

实现单例的代价太大了,每次加载类都需要上锁。但是在实际业务开发中,同步的场景很少,有点影响程序效率。

**优化方案二:**双重校验锁

通过synchronize 和 volatile 双重加锁,synchronize 保证了同一时间内有且只有一个线程可以进行初始化操作,volatile 不同线程访问的instance的实例一定都是主内存的中的东西。

public class Singleton {  
    private volatile static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {  
    if (singleton == null) {  
        synchronized (Singleton.class) {  
            if (singleton == null) {  
                singleton = new Singleton();  
            }  
        }  
    }  
    return singleton;  
    }  
}
静态内部类(利用classLoader机制)

懒加载机制,类加载的时候并没有进行初始化,只有在需要的时候才会加载SingletonHolder

public class Singleton {  
    private static class SingletonHolder {  
    	private static final Singleton INSTANCE = new Singleton();  
    }  
    private Singleton (){}  
    public static final Singleton getInstance() {  
    return SingletonHolder.INSTANCE;  
    }  
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值