饿汉模式
在类初始化阶段生成,使用时候不需要创建速度快,缺点是一直存放在内存中,如果不会用到就浪费内存。
1
2
3
4
5
6
7
| public final class Singleton {
private static Singleton instance=new Singleton();// 自行创建实例
private Singleton(){}// 构造函数
public static Singleton getInstance(){// 通过该函数向整个系统提供实例
return instance;
}
}
|
懒汉模式
使用double-check方式创建线程安全的单例。缺点,并发时可能会出现多次获取锁,效率不高。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| // 懒汉模式 + synchronized 同步锁 + double-check + volatile
public final class Singleton {
private volatile static Singleton instance= null;// 不实例化
public List<String> list = null;//list 属性
private Singleton(){
list = new ArrayList<String>();
}// 构造函数
public static Singleton getInstance(){// 加同步锁,通过该函数向整个系统提供实例
if(null == instance){// 第一次判断,当 instance 为 null 时,则实例化对象,否则直接返回对象
synchronized (Singleton.class){// 同步锁
if(null == instance){// 第二次判断
instance = new Singleton();// 实例化对象
}
}
}
return instance;// 返回已存在的对象
}
}
|
静态内部类实现懒汉模式
内部静态类在第一次使用的时候初始化,和饿汉模式相同,都是使用JVM的机制保证只有一个线程创建实例,其他线程会被阻塞。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| // 懒汉模式 内部类实现
public final class Singleton {
private Singleton(){
}
// 内部类实现
public static class InnerSingleton {
private static Singleton instance=new Singleton();// 自行创建实例
}
public static Singleton getInstance() {
return InnerSingleton.instance;// 返回内部类中的静态变量
}
}
|
枚举实现懒汉模式
和内部类相似,可读性还不如内部类,所以还是推荐使用内部类实现单例。这个看看就行2333…。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| public class SinletonExample {
private static SinletonExample instance = null;
// 私有构造函数
private SinletonExample() {
}
public static SinletonExample getInstance() {
return Sinleton.SINLETON.getInstance();
}
private enum Sinleton{
SINLETON;
private SinletonExample singleton;
// JVM保证这个方法只调用一次
Sinleton(){
singleton = new SinletonExample();
}
public SinletonExample getInstance(){
return singleton;
}
}
}
|