单例模式

单例设计模式

1、什么是 Singleton ?

  • Singleton:在 Java 中即指单例设计模式,它是软件开发中最常用的设计模式之一。
  • 单:唯一
  • 例:实例
  • 单例设计模式,即某个类在整个系统中只能有一个实例对象可被获取和使用的代码模式。
  • 例如:代表 JVM 运行环境的 Runtime 类。

2、要点

1)某个类只能有一个实例(构造器私有化)
2)它必须自行创建实例(​ 含有一个该类的静态变量来保存这个唯一的实例)
3)它必须自行向整个系统提供这个实例(对外提供获取该类实例对象的方式直接暴露,用静态变量声明的方法获取)

3、常见的形式

常见单例有三种饿汉式和三种懒汉式共六种。

饿汉式:直接创建对象,不存在线程安全问题。

1)直接实例化饿汉式(简洁直观)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* 直接实例化饿汉式
*/
public class Code_02_Singleton1 {

/**
* 1、构造器私有化
* 2、自行创建,并且用静态变量保存
* 3、向外提供实例
* 4、强调这是一个单例,我们可以用final修改
*/
public static final Code_02_Singleton1 INSTANCE = new Code_02_Singleton1();

private Code_02_Singleton1() {

}

}

2) 静态代码块饿汉式(适合复杂实例化)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 静态代码块饿汉式(适合复杂实例化)
*/
public class Code_02_Singleton2 {

public static final Code_02_Singleton2 INSTANCE;

static {
INSTANCE = new Code_02_Singleton2();
}

private Code_02_Singleton2() {

}

}

3)枚举式 (最简洁)

1
2
3
4
5
6
7
8
9
/**
* 枚举式 (最简洁)
*/
public enum Code_02_Singleton3 {
/**
* 枚举类型:表示该类型是有限的几个
*/
INSTANCE
}

懒汉式:延迟创建对象。

1)线程不安全(适用于单线程)

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 Code_02_Singleton4 {

/**
* 1、构造器私有化
* 2、用一个静态变量保存这个唯一的实例
* 3、提供一个静态方法,获取这个实例对象
*/
public static Code_02_Singleton4 instance;

private Code_02_Singleton4() {

}

public static Code_02_Singleton4 getInstance() {

if(instance == null) {
instance = new Code_02_Singleton4();
}

return instance;
}

}

2)双重检查(线程安全,适用于多线程)

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 Code_02_Singleton5 {

// 加 volatile 作用:防止指令重排, 当实例变量有修改时,能刷到主存中去是一个原子操作,并且保证可见性。
public static volatile Code_02_Singleton5 instance;

private Code_02_Singleton5() {

}

public static Code_02_Singleton5 getInstance() {
if(instance == null) {
synchronized (Code_02_Singleton5.class) {
if(instance == null) {
instance = new Code_02_Singleton5();
}
}

}
return instance;
}

}


3)静态内部类模式 (适用于多线程)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* 静态内部类模式 (适用于多线程)
*/
public class Code_02_Singleton6 {

/**
* 1、内部类被加载和初始化时,才创建INSTANCE实例对象
* 2、静态内部类不会自动创建, 不会随着外部类的加载初始化而初始化,他是要单独去加载和实例化的
* 3、因为是在内部类加载和初始化时,创建的,因此线程安全
*/
public static class Inner {
private static final Code_02_Singleton6 INSTANCE = new Code_02_Singleton6();
}

private Code_02_Singleton6() {

}

public static Code_02_Singleton6 getInstance() {
return Inner.INSTANCE;
}
}

总结:
1、如果是饿汉式,枚举形式最简单
2、如果是懒汉式,静态内部类形式最简单


单例模式
http://example.com/2018/07/31/单例模式/
作者
shoukailiang
发布于
2018年7月31日
许可协议