004.创建者模式_单例模式

1 单例模式

保证在整个的软件系统中,对某个类只能存在一个对象实例, 并且该类只提供一个取得其对象实例的方法(静态方法)。

使用场景:需要频繁的进行创建和销毁的对象、创建对象时耗时过多或耗费资源过多(即:重量级对象),但又经常用到的对象、工具类对象、频繁访问数据库或文件的对象(比如数据源、session 工厂等)。

2 饿汉式**(静态常量)** -> 推荐

1
2
3
4
5
6
7
8
9
10
11
//饿汉式(静态变量)
public class Singleton01 {
private final static Singleton01 instance = new Singleton01();

private Singleton01() {
}

public static Singleton01 getInstance() {
return instance;
}
}

优点:写法简单,就是在类装载的时候就完成实例化,避免了线程同步问题。

缺点:在类装载的时候就完成实例化,没有达到 Lazy Loading 的效果。如果没有使用,则会造成内存的浪费。

3 饿汉式(静态代码块)-> 推荐

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//饿汉式(静态代码块)
public class Singleton02 {
private static Singleton02 instance;

static {
instance = new Singleton02();
}

private Singleton02() {
}

public static Singleton02 getInstance() {
return instance;
}
}

这种单例模式可用,但是可能造成内存浪费。

4 懒汉式(线程不安全)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//懒汉式(线程不安全)
public class Singleton03 {
private static Singleton03 instance;

private Singleton03() {
}

public static Singleton03 getInstance() {
if (instance == null) {
instance = new Singleton03();
}
return instance;
}
}

优点: Lazy Loading 的效果,只能在单线程下使用。

缺点:线程不安全。

5 懒汉式(线程安全,同步方法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//懒汉式(线程安全,同步方法)
public class Singleton04 {
private static Singleton04 instance;

private Singleton04() {
}

public static synchronized Singleton04 getInstance() {
if (instance == null) {
instance = new Singleton04();
}
return instance;
}
}

优点:解决了线程安全问题。

缺点:效率低,每个线程在想获得类的实例时候,执行 getInstance() 方法都要进行同步。

6 懒汉式(线程安全,同步代码块)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//懒汉式(线程安全,同步代码块)
public class Singleton05 {
private static Singleton05 instance;


private Singleton05() {
}

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

优点:解决了线程安全问题。

缺点:效率低,每个线程在想获得类的实例时候,执行 getInstance() 方法都要进行同步。

7 双重检查(DCL) -> 推荐

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//懒汉式(线程安全,同步代码块)
public class Singleton06 {
private static volatile Singleton06 instance;

private Singleton06() {
}

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

线程安全;延迟加载;效率较高。

8 静态内部类 -> 推荐

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//静态内部类完成, 推荐使用
public class Singleton07 {

private Singleton07() {
}

public static class SingletonInstance {
private static final Singleton07 INSTANCE = new Singleton07();
}

public static Singleton07 getInstance() {
return SingletonInstance.INSTANCE;
}
}

线程安全,利用静态内部类特点实现延迟加载,效率高。

9 枚举 -> 推荐

1
2
3
4
//枚举
public enum Singleton08 {
INSTANCE;
}

不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象。