高并发下的单例设计模式

熟悉Java的朋友应该对单例设计模式了解的不少,比如我们会发现Spring中默认交给容器管理的对象都是单例的,除非你手动的设置。那么Spring是如何保证容器中的Bean对象只创建一次呢?下面,我们就分析一下单设计及模式与并发碰撞在一起会出现怎样的火花。

 

懒汉模式和饿汉模式得区别

懒汉模式就是懒,不用它就不创建,等到要用的时候才创建(赶晚不赶早)

饿汉模式就是饿死鬼,还没到用到得时候他就创建出来,就像还没有到吃饭的时间,就早早把饭做好了。(赶早不赶晚)。

 

 

一.懒汉模式

 

 

1.懒汉设计模式(一挡!)。


/**
 * 懒汉模式(一挡)
 *
 */
@Slf4j
@UnThreadSafe//这两个注解你不需要关心
public class test_Singleton_lazy{
    //获取实例对象

    @Test
    public void fun1(){

        /**
         * 下面的意思就是开50个线程,并发的获取Singleton_Lazy的实例
         * 
         */

        ExecutorService executorService = Executors.newCachedThreadPool();

        for(int i= 0 ; i< 50 ; i++){

            executorService.execute(()->{
                System.out.println("singleton_lazy1的HashCode为:"+Singleton_Lazy.getSingletion().hashCode());
            });
        }

    }

}

//最基本的单例设计模式,也是我们最先接触到的,在单线称下可以正确的运行,但是高并发下,就会出错!
class Singleton_Lazy {

    //构造函数私有化
    
    private Singleton_Lazy(){

    }
    //创建成员变量

    private static Singleton_Lazy singleton_lazy=null;

    //静态方法获取目标对象

    public static Singleton_Lazy getSingletion(){

        if(singleton_lazy == null){
            singleton_lazy = new Singleton_Lazy();
        }
        return singleton_lazy;
    }

}

 

高并发下的测试结果:

 

解释:上面我们开了50个线程同时获取Singleton_Lazy的实例,我们可以模拟一下线程。当一条线程通过下面的判断条件进入if块后,在还没来得及改变singleton_lazy的值或线程工作区虽然改变了但是还未及时刷新回内存的时候,另一个线程也通过了if判断,进入了if语句块内部,这时,后一个线程和前一个线程将持有不同的返回对象,单例模式被高并发破环!

if(singleton_lazy == null){
     singleton_lazy = new Singleton_Lazy();
}

下面我们对上面的懒汉设计模式进行升级!

 

 

2.懒汉设计模式(二挡!)

 

/**
 *
 * 单例设计模式,懒汉式(二挡)
 */
@Slf4j
@UnThreadSafe
public class test_Singleton_lazy_01 {

    @Test
    public void fun1(){

        /**
         * 下面的意思就是开50个线
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值