设计模式-单例

Posted 番茄红了

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式-单例相关的知识,希望对你有一定的参考价值。

单例

定义

确保一个类只有一个实例,并提供一个全局访问点

类图


构成:

  1. 私有构造器
  2. 静态方法
  3. 静态变量

代码

基础版

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();


以上是关于设计模式-单例的主要内容,如果未能解决你的问题,请参考以下文章

深入理解设计模式-单例模式(饿汉单例模式懒汉单例模式双锁单例模式)

单例模式单例模式精讲(上)

Java模式设计之单例模式(二)

设计模式之单例模式

java设计模式-单例模式

Java设计模式 - 单例模式