单例模式大比拼

单例模式大比拼

分类

  • 1、饱汉模式
  • 2、懒汉模式
  • 3、最佳模式(多线程安全)

1、饱汉模式

1
2
3
4
5
6
7
8
public final class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() {}
public static Singleton getInstance() {
return instance;
}
}

2、懒汉模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Singleton {
//一个静态的实例
private static Singleton singleton;
//私有化构造函数
private Singleton(){}
//给出一个公共的静态方法返回一个单一实例
public static Singleton getInstance(){
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}

上面2种情况在单线程的时候运行良好,多线程模式下会出现问题

解决办法:

(1)、你可以在方法上面加入synchronized关键字(性能低下,及其不推荐)

(2)、同步的地方只是需要发生在单例的实例还未创建的时候,在实例创建以后,获取实例的方法就没必要再进行同步控制了,所以我们将上面的示例改为很多教科书中标准的单例模式版本,也称为双重加锁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class SynchronizedSingleton {
//一个静态的实例
private static SynchronizedSingleton synchronizedSingleton;
//私有化构造函数
private SynchronizedSingleton(){}
//给出一个公共的静态方法返回一个单一实例
public static SynchronizedSingleton getInstance(){
if (synchronizedSingleton == null) {
synchronized (SynchronizedSingleton.class) {
if (synchronizedSingleton == null) {
synchronizedSingleton = new SynchronizedSingleton();
}
}
}
return synchronizedSingleton;
}
}

上面的双重加锁模式在语言层面是ok的,但是jvm层面还是会出问题的

下面一种方法不会出现多线程问题,保证一个实例

3、

1
2
3
4
5
6
7
8
9
10
11
12
public class InnerClassSingleton {
public static Singleton getInstance(){
return Singleton.singleton;
}
private static class Singleton{
protected static Singleton singleton = new Singleton();
}
}
Share