将单例的bean创建多个、单例模式(两种模式)

本文探讨如何在Spring容器中创建多个单例bean,包括通过注解和XML配置的方式。同时,文章详细介绍了单例模式的懒汉式和饿汉式实现,强调线程安全的重要性,并提供了线程相对安全和安全的单例模式实现方法,特别是volatile关键字在确保线程安全中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

将单例的bean创建多个

在spring容器中每个bean都是唯一的
怎么将单例的bean创建多个
两种实现方式
1 在类上加一个注解

@Scope("prototype")

2 在xml配置

<bean id=" " class="xxx.xxx.xxx" scope="prototype"></bean>

request:针对web项目,不同的请求创建单独的bean对象,同一个请求共享一个bean
session:针对web项目,不同的会话创建单独的bean对象,同一个会话共享一个bean
在Java体系中没有特殊要求默认都是单例的

单例模式:懒汉式;用的时候才创建

1 创建一个本身类的属性instance
2 创建一个该类的构造方法SingletonDemo,将该构造方法用private修饰,目的就是让其他类new不出
3 创建一个返回该类型的静态方法
4 在方法中先判断属性类instance是不是null,如果是null就给该属性赋值,赋的就是new该类(创建一个实例)
5 如果该属性类instance有值就返回该属性类

public class SingletonDemo {
private static SingletonDemo instance;
private SingletonDemo(){}
public static SingletonDemo getInstance(){
    if(instance==null){
                instance = new SingletonDemo();
            }
    return instance;
	}
}

以上是非线程安全的单例(高并发的情况下同时有多个线程判断到的都是instance==null,这个时候这几个线程就会创建相同的实例,这样就违背了单例模式的初衷)

线程相对安全的单例

方式一:在创建实例赋值的方法上加一个关键字synchronized(加在方法的访问权限后)
该关键字的意思是在同一时间只会被同一线程访问

public class SingletonDemo {
private static SingletonDemo instance;
private SingletonDemo(){}
public synchronized static SingletonDemo getInstance(){
    if(instance==null){
                instance = new SingletonDemo();
            }
    return instance;
	}
}

方式二: synchronized (SingletonDemo.class)的意思就是
当发现instance==null的时候同步整个代码块,将 instance = new SingletonDemo()放在整个执行安全的过程中

public class SingletonDemo {
private volatile static SingletonDemo instance;
private SingletonDemo(){}
public static SingletonDemo getInstance(){
    if(instance==null){
        synchronized (SingletonDemo.class){
            if(instance==null){
                instance = new SingletonDemo();
            }
        }
    }
    return instance;
	}
}

以上写法还是会创建多个对象,这个原因跟写法没有关系,是因为,java代码执行高并发时(为了运算速度快)会将主线程复制为一个副本,虽然instance属性是定义在主线程中的,但是执行时被拆分的副本也会同时执行,这样就会取到jvm优化、计算过程中的值,这是jvm对线程进行优化的部分,做一个缓存机制,这样还是会有问题;解决该方法比较简单,就是在属性类instance上加一个关键字volatile,意思就是每次取该属性值时都是在源头上取值,不是从副本里取值

线程安全的单例

public class SingletonDemo {
private volatile static SingletonDemo instance;
private SingletonDemo(){}
public static SingletonDemo getInstance(){
    if(instance==null){
        synchronized (SingletonDemo.class){
            if(instance==null){
                instance = new SingletonDemo();
            }
        }
    }
    return instance;
}
}

单例模式:饿汉式;程序启动加载资源时就创建好

public Simple(){
 private static Single s=new Single();        
 private Single(){}  
 public static Simple getSimple(){
     return s;
 } 
}    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值