单例设计模式(Singleton Design Pattern)理解起来非常简单。一个类只允许创建一个对象(或者实例),那这个类就是一个单例类,这种设计模式就叫作单例设计模式,简称单例模式。
1. 饿汉式
class Signle{
private Signle(){}
private static final Signle instance=new Signle();
public static Signle getInstance() { return instance; }
}
优点:
在类加载的时候,instance 静态实例就已经创建并初始化好了,所以,instance 实例的创建过程是线程安全的.
2. 懒汉式
public class IdGenerator {
private AtomicLong id = new AtomicLong(0);
private static IdGenerator instance;
private IdGenerator() {}
public static IdGenerator getInstance() {
if (instance == null) {
synchronized(IdGenerator.class) { // 此处为类级别的锁
if (instance == null) {
instance = new IdGenerator();
}
}
}
return instance;
}
public long getId() {
return id.incrementAndGet();
}
}
优点:
懒汉式相对于饿汉式的优势是支持延迟加载。
缺点:
不过懒汉式的缺点也很明显,我们给 getInstance() 这个方法加了一把大锁(synchronzed),导致这个函数的并发度很低。量化一下的话,并发度是 1,也就相当于串行操作了。而这个函数是在单例使用期间,一直会被调用。如果这个单例类偶尔会被用到,那这种实现方式还可以接受。但是,如果频繁地用到,那频繁加锁、释放锁及并发度低等问题,会导致性能瓶颈,这种实现方式就不可取了。
3.内部静态类
class Signle{
private Signle(){}
private static class SignleHolder{
private static Signle SIGNLE=new Signle();
}
public static Signle getInstance(){
return SignleHolder.SIGNLE;
}
}
优点:
SingletonHolder 是一个静态内部类,当外部类 Signle 被加载的时候,并不会创建 SingletonHolder 实例对象。只有当调用 getInstance() 方法时,SingletonHolder 才会被加载,这个时候才会创建 instance。instance 的唯一性、创建过程的线程安全性,都由 JVM 来保证。所以,这种实现方法既保证了线程安全,又能做到延迟加载
4.枚举
public enum Signle {
INSTANCE;
}
5.应用场景:
1.Logger
2.配置类
3.Spring工厂类