设计模式之单件模式

用户头像
Geek_896619
关注
发布于: 2020 年 06 月 09 日

本章关键词:延迟初始化,多线程,线程安全,双重检查加锁,java版本,类加载器




1.定义

单件模式:确保一个类仅有一个实例,并提供一个全局访问点

2.应用点

单件模式常常被用作管理共享的资源:如数据库连接或者线程池等。

3.实现

public class singleton {
//单件模式实例引用
private static singleton single;
private singleton() {
}
public static singleton getInstance() {
//延迟初始化:第一次访问静态方法的时候才初始化对象
if(single == null) { //①
single = new singleton();
}
return single;
}
}



4.优势&缺点

优点:单件模式具有延迟初始化的作用【见 3 实现】



5.使用注意点

多线程问题:当多线程访问单件模式类时,如果两条线程同时访问 3实现 中的代码①处时,会初始化两个对象,此时就不是线程安全的了。



怎么解决呢?

方法一:把方法设为同步级别。如果单件模式的对象访问方法对程序性能影响不大,大可把方法级别设为同步级别,方法名增加修饰词 synchronized 即可。

适用情况:访问方法对程序性能影响不大,可使用直接同步。



方法二:急切加载的单件模式。

优点:不需要同步也是线程安全的。

缺点:不需要的实例也会被初始化出来。

实现如下:

public class singleton {
//急切加载的单件模式,类初始化时就进行加载
private static singleton single = new singleton();
private singleton() {
}
public static singleton getInstance() {
return single;
}
}

适用情况:同步方法对性能有要求,且单件实例初始化不需要考虑初始化时机。



方法三:双重检查加锁。

使用双重检查加锁来减少getInstance方法中同步的使用。

实现:【待完善】

优缺点:【待完善】

适用情况:【待完善】



类加载器问题:两个不同的类加载器可能会生成多个单件实例。

问题出现原因:因为不同的类加载器都定义了不同的命名空间,当它们加载同一个类时,就会生成2个不同的单件实例。

如何解决:自行指定类加载器,并指定同一个类加载器 来加载类。

6.总结

单例模式是一种常用的设计模式,它保证一个类仅能初始化一个实例,并提供全局的访问点。

单例模式经常使用在资源管理的场景,包括数据库连接,线程池等。

使用单例模式时,还需要注意线程安全等问题,当需要处理线程安全问题时,应该根据具体的业务场景选择合适的方法进行解决。例如,对性能有无要求,对加载时机有无要求等等。



用户头像

Geek_896619

关注

还未添加个人签名 2018.11.08 加入

还未添加个人简介

评论

发布
暂无评论
设计模式之单件模式