设计模式之单例模式

单例模式

单例模式介绍

单例模式(Singleton Pattern)是 设计模式中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

单例模式UML

95409683.jpg

单例模式实现

1、饿汉式(静态常量)

1
2
3
4
5
6
7
8
9
10
public class Singleton {

private final static Singleton INSTANCE = new Singleton();

private Singleton(){}

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

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

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

2、饿汉式(静态代码块)

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

private static Singleton instance;

static {
instance = new Singleton();
}

private Singleton() {}

public Singleton getInstance() {
return instance;
}
}

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

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

3、懒汉式(线程不安全)

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

private static Singleton singleton;

private Singleton() {}

public static Singleton getInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}

这种写法容易在多个线程线程同时进入if (singleton == null)时,导致创建多个Singleton对象,无法实现单例要求。

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

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

private static Singleton singleton;

private Singleton() {}

public static synchronized Singleton getInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}

解决了线程同步的安全问题,但是在每一个线程想要获得类的实例时,都需要进行同步,将导致同步效率过慢。

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

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

private static Singleton singleton;

private Singleton() {}

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

该方法因为当两个线程同时通过 if (singleton == null)代码块时,因为synchronized (Singleton.class)的同步问题,一个线程先进入其中建立一个类的实例,第二个线程在第一个线程创建完实例后进入创建第二个实例,因此改写法将导致出现多个实例。

6、双重检查

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

private static volatile Singleton singleton;

private Singleton() {}

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

该写法可以做到线程安全;延迟加载;效率较高。

7、静态内部类

1
2
3
4
5
6
7
8
9
10
11
12
public class Singleton {

private Singleton() {}

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

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