单例模式

特征

在运行时阶段只能有一个对应类的实例对象

实现要点

  • 私有构造

似有构造控制对象的构建权利, 只赋给类本身

  • 对外的实例引用

单例的使用入口

饿汉式实现

要点: 静态属性, 直接在类初始化时实现

1
2
3
4
5
6
7
8
9
10
11
12
package com.luozi.designpatterns.singleton;

public class A {
private final static A INSTANCE = new A();

private A() {
}

public static A getInstance() {
return INSTANCE;
}
}

对象什么时候实例化呢, 类的生命周期中, 当类被直接引用的(一般是使用类的时候, 具体参照类的生命周期那片文章)时候, 会触发类的初始化, 这个时候就会依次执行类中的静态语句, 这里是创建单例

懒汉式实现

要点: 双重校验, 在获取单例时实例化; volatile 关键字保证值在线程间可见

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.luozi.designpatterns.singleton;

public class B {
// 加上volatile关键字, 保证属性的读在线程见可见
private static volatile B INSTANCE;

private B() {
}

public static B getInstance() {
if (INSTANCE == null) {
// 当 INSTANCE 为 null的时候, 使用锁, 保证只生成一个 实例
// 只在 INSTANCE 为null的时候使用锁, 而不是在方法上使用 锁, 提高效率
synchronized (B.class) {
// 在拿到索后, 还需要再次校验一下是否为 null, 因为可能好几个线程都走到拿到锁这一步了
// 要避免第二个及后面拿到锁的 线程重新生成对象, 同时这里使用 volatile 关键字, 保证值在线程中可见
if (INSTANCE == null) {
INSTANCE = new B();
}
}
}
return INSTANCE;
}
}