设计模式-单例模式

单例模式

多个线程操作不同实例对象。多个线程要操作同一对象,要保证对象的唯一性

单例模式的特点

  1. 有一个实例化的过程(只有一次),产生实例化对象
  2. 提供返回实例对象的方法

单例模式的分类

饿汉式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class HungrySingleton {
//加载时就产生了实例对象
private static HungrySingleton instance = new HungrySingleton();

private HungrySingleton() {
}
//返回实例对象
public static HungrySingleton getInstance() {
return instance;
}

public static void main(String[] args) {
for(int i = 0 ; i < 10 ; i ++){
new Thread(()->{
HungrySingleton hungerySingleton = HungrySingleton.getInstance();
System.out.println(hungerySingleton);
}).start();
}
}
}
  • 线程安全性:在加载的时候已经被实例化,所以只有这一次,线程安全的。
  • 懒加载:没有延迟加载
  • 性能:长时间不使用,数据一直放在堆中影响性能

懒汉式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class LazySingleton {
private static LazySingleton instance = null;

private LazySingleton() {
}

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

public static void main(String[] args) {
for(int i = 0 ; i < 10 ; i ++){
new Thread(()-> System.out.println(LazySingleton.getInstance())).start();
}
}
}
  • 线程安全性:不能保证实例对象的唯一性
  • 懒加载:有延迟加载
  • 性能:使用时才进行加载,性能较好

懒汉式+同步方法

将懒汉式的get方法加上synchronized

1
2
3
4
5
6
public synchronized static LazySingleton getInstance() {
if(instance == null){
instance = new LazySingleton();
}
return instance;
}
  • 线程安全性:synchronized保证线程安全
  • 懒加载:有延迟加载
  • 性能:多个线程调用该方法时 synchronized 会使线程阻塞,退化到了串行执行

Double-Check-Locking

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class DCLSingleton {
private static DCLSingleton instance = null;

private DCLSingleton() {
}

public static DCLSingleton getInstance() {
if(instance == null){
synchronized (DCLSingleton.class){
if(instance == null){
instance = new DCLSingleton();
}
}
}
return instance;
}
public static void main(String[] args) {
for(int i = 0 ; i < 10 ; i ++){
new Thread(()-> System.out.println(DCLSingleton.getInstance())).start();
}
}
}
  • 线程安全性:线程安全
  • 懒加载:有延迟加载
  • 性能:性能比较好
  • 缺点:会因为指令重排,引起空指针异常。

Volatile+Double-check

添加volatile 避免空指针异常。

1
private volatile static DCLSingleton instance = null;

Holder

声明类的时候,成员变量中不声明实例变量,而放到内部静态类中,

1
2
3
4
5
6
7
8
9
10
11
public class HolderSingleton {
private HolderSingleton() {
}
//通过内部类实现懒加载,只有调用时才会进行实例化,静态类只能实例一次,保证线程安全
private static class Holder{
private static HolderSingleton instance=new HolderSingleton();
}
public static HolderSingleton getInstance(){
return Holder.instance;
}
}

枚举

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class EnumSingleton {
private EnumSingleton() {
}
//延迟加载
private enum EnumHolder{
INSTANCE;
private EnumSingleton instance=null;

EnumHolder() {
this.instance = new EnumSingleton();
}
}
public static EnumSingleton getInstance(){
return EnumHolder.INSTANCE.instance;
}
}
-------- 本文结束 感谢阅读 --------

本文标题:设计模式-单例模式

文章作者:Guyuqing

发布时间:2020年02月29日 - 17:37

最后更新:2020年03月06日 - 20:44

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

坚持技术分享,您的支持将鼓励我继续创作!
0%