Spring Boot 编程思想学习笔记——isSingleton 单例模式

  • Post author:
  • Post category:其他

spring配置文件中有个属性isSingleton ——是否单例

isSingleton 方法则判断 Bean 是否在 Spring IoC 中为单例。这里需要记住的是在 Spring IoC 容器 中,默认的情况下, Bean 都是以单例存在的,也就是使用 getBean 方法返回的都是同一个对象。与 isSingleton 方法相反的是 isPrototype 方法,如果它返回的是 true,那么当我们使用 getBean 方法获取Bean 的时候, Spring IoC 容器就会创建一个新的 Bean 返回给调用者。

springboot中

@ComponentScan ( lazyinit = true) :延迟实例化 lazyinit 关键字实现延迟实例化

在多将一些单例模式(单件模式)

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

实现方式:类的构造方式私有化,在类里私有定一个变量,然后提供公有方法getInstance,在getInstance方法里创建获取提供对象,并保证类只能被实例化一次。

代码如下:

public class Singleton{
    private static Singlegon uniqueInstace;
    private Singleton(){
        
    }
    public static Singleton getInstance(){
        if(uniqueInstance == null){
            uniqueInsance = new Singleton();
        }
        return uniqueInstance;
    }
}

代码中,当外部调用Singleton类时,采取实例化对象,这叫做延迟实例化,当不需要这个实例时,它就用于不会产生,可以不浪费资源。

单件模式和多线程

上述代码实现的单件模式是不支持多线程的,有三种方式解决多线程问题

1同步:在getInstance方法上使用synchronized关键字,但这会造成效率下降。

2不使用延迟实例化:

public class Singleton{
    private static Singlegon uniqueInstace = new Singleton();
    private Singleton(){
        
    }
    public static Singleton getInstance(){
        return uniqueInstance;
    }
}

这要求JVM加载这个类时就会创建实例。会造成资源浪费。

3双重检查加锁

使用volatile关键字。

  • 保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。(实现可见性)
  • 禁止进行指令重排序。(实现有序性)
  • volatile 只能保证对单次读/写的原子性。i++ 这种操作不能保证原子性
public class Singleton{
    private static volatile Singlegon uniqueInstace;
    private Singleton(){
        
    }
    public static Singleton getInstance(){
        if(uniqueInstance == null){
            synchronized(Singleton.class){
                if(uniqueInstance == null){
                    uniqueInsance = new Singleton();
                }                
            }
            
        }
        return uniqueInstance;
    }
}

只有第一次是才会进入同步区块。解决了单件模式的多线程问题


版权声明:本文为yaovirus原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。