单例模式的几种实现方式

1. 饿汉式(线程安全,调用效率高,但是不能延时加载):

1
2
3
4
5
6
7
public class Singleton{ 
private static Singleton instance = new Singleton;
private Singleton(){}
public static Singleton getInstance(){
return instance;
}
}

一上来就把单例对象创建出来了,要用的时候直接返回即可,这种可以说是单例模式中最简单的一种实现方式。但是问题也比较明显。单例在还没有使用到的时候,初始化就已经完成了。也就是说,如果程序从头到位都没用使用这个单例的话,单例的对象还是会创建。这就造成了不必要的资源浪费。所以不推荐这种实现方式。

2. 懒汉式(线程安全,调用效率不高,但是能延时加载)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Singleton {

//类初始化时,不初始化这个对象(延时加载,真正用的时候再创建)
private static Singleton instance;

//构造器私有化
private Singleton(){}

//方法同步,调用效率低
public static synchronized Singleton getInstance(){
if(instance==null){
instance=new Singleton();
}
return instance;
}
}

3. Double CheckLock实现单例:DCL也就是双重锁判断机制(由于JVM底层模型原因,偶尔会出问题,不建议使用)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Singleton{
private static volatile Singleton singleton;

private Singleton(){}

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

4. 静态内部类实现模式(线程安全,调用效率高,可以延时加载)

1
2
3
4
5
6
7
8
9
10
11
public class SingletonDemo3 {
private static class SingletonClassInstance{
private static final SingletonDemo3 instance=new SingletonDemo3();
}

private SingletonDemo3(){}

public static SingletonDemo3 getInstance(){
return SingletonClassInstance.instance;
}
}

5.枚举类(线程安全,调用效率高,不能延时加载,可以天然的防止反射和反序列化调用)

1
2
3
4
5
6
public enum Singleton{
INSTANCE;
public void doSomething() {
System.out.println("doSomething");
}
}

参考文献

  1. https://www.cnblogs.com/happy4java/p/11206105.html
  2. https://www.cnblogs.com/shujiying/p/13127418.html