设计模式-单例
Posted 番茄红了
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式-单例相关的知识,希望对你有一定的参考价值。
定义
确保一个类只有一个实例,并提供一个全局访问点
类图
构成:
- 私有构造器
- 静态方法
- 静态变量
代码
基础版
public class Singleton{
//利用静态变量来记录Singleton类的唯一实例
private static Singleton uniqueInstance;
//声明私有构造器,私有在Singleton类中才可以调用该方法
private Singleton(){}
//实例化对象,并返回该示例
public static Singleton getInstance(){
if(uniqueInstance==null){
uniqueInstance=new Singleton();
}
return uniqueInstance;
}
}
基础版的缺点?
多线程会实例化出多个对象。
- 如果现在有多个线程,并且都在未实例化对象前进入,则都不满足uniqueInstance==null的条件,那么就会根据线程创建出多个实例对象。
解决线程问题版本
同步getInstance方法
public class Singleton{
private static Singleton uniqueInstance;
private Singleton{};
private static synchornized Singleton getInstance(){
if(uniqueInstance==null){
uniqueInstance=new Singleton();
}
return uniqueInstance;
}
}
更改点:
- synchornized(同步锁):
使用该关键字使得每个线程在进入这个方法之前,需要等候别的线程离开该方法(加锁)。线程进到该方法就加锁,
等前面的线程处理完,再让后续访问的线程进入该方法
该方法有缺点吗?
- 有的。 同步会减低性能:https://www.zhihu.com/question/29802671/answer/1265735136
急切实例化(改善多线程)
public class Singleton{
//在静态初始化器中创建单件,此段代码JVM保证了线程安全
private static Singleton uniqueInstance = new Singleton();
private Singleton{};
public static Singleton getInstance(){
return uniqueInstance;
}
}
jvm保证了线程的安全:https://www.cnblogs.com/little-mao2020/p/14673899.html
静态内部类的特点:外部类加载时不需要加载静态内部类,不被加载则不占用内存,(延迟加载)当外部类调用getInstance方法时,才加载静态内部类,静态属性保证了全局唯一,静态变量初始化保证了线程安全
双重检查加锁(改善多线程)
减少同步
public class Singleton{
private volatile static Singleton uniqueInstance;
private Signleton(){};
public static Singleton getInstance(){
//检查实例,如果不存在,就进入同步
if(uniqueInstance==null){
synchronized(Sigleton.class){
//再检查一次,如果还是null则创建实例
if(uniqueInstance==null){
uniqueInstance=new Sigleton();
}
}
}
}
}
如何减少的同步?
- 先判断了实例是否存在,存在就不往后进行了,则线程不需要一致等待。
解决线程同步&防止序列化
public enmu Singleton{
Instance;
public void m(){};
}
以上是关于设计模式-单例的主要内容,如果未能解决你的问题,请参考以下文章