kim.zhang

风在前,无惧!


  • 首页

  • 标签42

  • 分类12

  • 归档94

  • 搜索

单例模式.md

发表于 2020-08-10 更新于 2021-11-21 分类于 设计模式
本文字数: 2.4k 阅读时长 ≈ 2 分钟

1.饿汉式->静态常量[可用]

1
2
3
4
5
6
7
8
9
10
public class Singleton1 {
// 在类加载的时候初始化
private final static Singleton1 instance = new Singleton1();

private Singleton1(){}

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

2.饿汉式->静态代码块[可用]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Singleton2 {

private final static Singleton2 instance;

// 在静态代码块中初始化
static {
instance = new Singleton2();
}

private Singleton2() {
}

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

3.懒汉式->线程不安全

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Singleton3 {

private static Singleton3 instance;



private Singleton3() {
}

// 懒汉式,在实例不为空时,直接返回实例对象,为空时,创建一个实例返回
// 如果多个线程同时进入if语句,会导致线程不安全
public static Singleton3 getInstance() {
if(instance == null){
instance = new Singleton3();
}
return instance;
}
}

4.懒汉式->线程安全

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Singleton4 {

private static Singleton4 instance;


private Singleton4() {
}

// 加锁保证线程安全,效率低下
public static synchronized Singleton4 getInstance() {
if (instance == null) {
instance = new Singleton4();
}
return instance;
}
}

5.懒汉式->线程不安全

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Singleton5 {

private static Singleton5 instance;


private Singleton5() {
}

// 目的是为了降低锁的粒度,提高性能,但没达到线程安全
// 如果第一个线程创建了对象,释放锁,第二个线程进来,又创建了一个新的对象
public static Singleton5 getInstance() {
if (instance == null) {
synchronized (Singleton5.class){
instance = new Singleton5();
}
}
return instance;
}
}

6.双重检查[推荐使用]

优点:线程安全,效率较高

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Singleton6 {
// volatile保证可见性和禁止重排序,对象的创建过程不是原子性的,会有重排序的可能
private volatile static Singleton6 instance;


private Singleton6() {
}

// 双重检查
public static Singleton6 getInstance() {
if (instance == null) {
synchronized (Singleton6.class) {
if (instance == null) {
instance = new Singleton6();
}
}
}
return instance;
}
}

7.静态内部类[推荐用]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Singleton7 {

private Singleton7() {
}

static class Singleton7Inner {
private static final Singleton7 instance = new Singleton7();
}

// 返回静态内部类创建的实例,由JVM保证线程安全
public static Singleton7 getInstance() {
return Singleton7Inner.instance;
}
}

8.枚举

1
2
3
4
5
6
7
8
public enum Singleton8 {
INSTANCE;

// 只是为了示范调用INSTANCE的方法,实际上一行代码就完成了INSTANCE的单例模式
public void whatever() {

}
}

各种写法的适用场合

  • 最好的方法是利用枚举,因为还可以防止反序列化重新创建新的对象
  • 非线程安全的方法不能使用
  • 如果程序一开始要加载的资源太多,那么就应该使用懒加载
  • 饿汉式如果是对象的创建需要配置文件就不适用
  • 懒加载虽然好,但是静态内部类这种方式会增加编程的复杂性
一毛也是爱~
Kim.Zhang 微信支付

微信支付

# 单例模式
可见性.md
volatile.md
  • 文章目录
  • 站点概览
Kim.Zhang

Kim.Zhang

且行且珍惜
94 日志
12 分类
42 标签
E-Mail Weibo
  1. 1. 1.饿汉式->静态常量[可用]
  2. 2. 2.饿汉式->静态代码块[可用]
  3. 3. 3.懒汉式->线程不安全
  4. 4. 4.懒汉式->线程安全
  5. 5. 5.懒汉式->线程不安全
  6. 6. 6.双重检查[推荐使用]
  7. 7. 7.静态内部类[推荐用]
  8. 8. 8.枚举
  9. 9. 各种写法的适用场合
粵ICP备19091267号 © 2019 – 2022 Kim.Zhang | 629k | 9:32
本站总访问量 4 次 | 有 309 人看我的博客啦 |
博客全站共176.7k字
载入天数...载入时分秒...
0%