建造型设计模式
简要定义
确保一个类还有一个实例,能够提供一个全局访问点.
实现方法
public class Singleton{
private static Singleton unipueInstance;// 利用静态变量记录唯一实例
//其他有用变量
private Singleton(){} //把构造器声明为私有,只有Singleleton才能调用
public static Singleton getInstance(){
if(uniqueInstance == null){
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
多线程处理
多线程可能会实例化多个uniqueInstance
改善多线程
- "急切"创建实例,而不是延迟实例化(适用于创建和运行时该方面的负担不太繁重)
public class Singleton{
private static Singleton unipueInstance = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return uniqueInstance;
}
}
- 使用"双重检查加锁"
public class Singleton{
private volatile static Singleton unipueInstance;
//其他有用变量
private Singleton(){} //把构造器声明为私有,只有Singleleton才能调用
public static Singleton getInstance(){
if(uniqueInstance == null){
synchronized (Singleton.class){
if(uniqueInstance == null) {
uniqueInstance = new Singleton();
}
}
}
return uniqueInstance;
}
}
优缺点
优点
- 可以避免对共享资源的多重占用
- 因为单例模式在系统内存中只存在一个对象, 因此可以节约系统资源.
- 使用方便
缺点
- 如果同一对象要在不同的用例场景发生变化是, 单例模式不能保存彼此状态
- 由于构造方法是私有的, 因此该类不能被继承, 因此, 单例模式的拓展有一定的困难
- 介于某些语言(java c#)的运行环境提供了自动垃圾回收的技术, 如果是实例化的对象长时间不被使用, 系统会默认销毁对象, 并回收资源, 这样会导致对象状态的丢失.
注: 官方文档: c# 内存管理与垃圾回收机制 实现Dispose方法
CSDN C#对象销毁与垃圾回收
使用场景
单例模式应用的场景一般发现在以下条件下:
(1)资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如上述中的日志文件,应用配置。
(2)控制资源的情况下,方便资源之间的互相通信。如线程池等。
具体应用
- 管理器类
- 网页计数器
- 多线程的线程池
关于volatile 关键字
Java提供了volatile关键字来保证可见性。
当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值。
而普通的共享变量不能保证可见性,因为普通共享变量被修改之后,什么时候被写入主存是不确定的,当其他线程去读取时,此时内存中可能还是原来的旧值,因此无法保证可见性。