饿汉模式

特点:基于类加载机制, 避免了多线程的同步问题,在类加载时期就已经生成。所以必定只有唯一一个。同时会降低类加载速度,而且如果这个实例不会被使用,会造成内存浪费。

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

懒汉模式(线程不安全)

1
2
3
4
5
6
7
8
9
10
11
public class Singleton{
private static Singleton instance;
private static Singketon(){
}
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}

懒汉模式(线程安全)

1
2
3
4
5
6
7
8
9
10
public class Singleton{
private static Singleton instance;
private Singleton(){}
public static synchronized Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}

双重检查模式(DCL)

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Singleton{
private volatile static Singleton singleton;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
synchronized (Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
}
}

静态内部类

特点:首先我们要明确一点,类加载的时候,外部类中的静态内部类是不会被加载的,只有在被调用的时候才会被加载。
这也是静态内部类方法区别于饿汉模式的地方。只有在 getInstance() 方法被调用后,才会产生实例,且唯一。

1
2
3
4
5
6
7
8
9
public class Singleton{
private Singleton(){}
public static Singleton getInstance(){
return SingletonHolder.sInstance;
}
private static class SingletonHolder{
private static final Singleton sInstance = new Singleton();
}
}

枚举单例

1
2
3
4
5
6
public enum Singleton{
INSTANCE;
public void doSomeThing(){
...
}
}

使用场景

  • 整个项目需要一个共享访问点或共享数据
  • 创建一个对象需要消耗的资源过多, 比如访问 I/O 或者数据库等资源。
  • 工具类对象