单例模式的懒汉模式为什么在高并发中会出现问题?一个代码例子告诉你

简介: 单例模式的懒汉模式为什么在高并发中会出现问题?一个代码例子告诉你

单例模式的懒汉模式为什么在高并发中会出现问题?一个代码例子告诉你


一、前言

我们对于单例模式我觉得是23种设计模式中大家最熟悉的一个,但是我们真的理解清楚了吗?小编最近才想到都说懒汉模式不合适出现在高并发中,会出现并发问题,于是小编研究了一下才发现,今天就带大家用一个例子来证明是不是高并发会出现错误!!


二、懒汉模式优缺点

- 优点:

懒汉式相对于饿汉式的优势是支持延迟加载

- 缺定:

懒汉式有性能问题,不支持高并发


三、案例分析

- 手机数量类:

import lombok.Data;
import java.util.concurrent.atomic.AtomicInteger;
@Data
public class Phone {
    //手机余额
    private AtomicInteger count = new AtomicInteger(3);
    private Phone(){}
    private static Phone phone;
    public static Phone getInstance(){
        if (phone == null){
            phone = new Phone();
        }
        return phone;
    }
    public int getReduce(){
        return count.decrementAndGet();
    }
}

- 高并发进行手机秒杀

public class BingFa {
    public static void main(String[] args) {
        // 创建3个线程,线程里面进行加操作
        for (int i = 0; i < 3; i++) {
            new Thread(() -> {
                Phone phone = Phone.getInstance();
                int reduce = phone.getReduce();
                System.out.println(Thread.currentThread().getName()+
                          "线程抢到了手机,剩余手机数量"+"-----"+reduce);
            }, String.valueOf(i)).start();
        }
    }
}

- 抢购结果展示


四、总结

从上面的结果来看,我们很明显的看出来,懒汉式在面对高并发的时候,出现了并发错误,也就是秒杀的买超了问题,我们这里是三个线程买到的都是一个手机,而不是三个手机。原因是因为三个线程可能都拿到了时间片,然后再懒汉式中判断phone == null,他们三个线程都以为为空都创建了一个对象,这样就成了new了三个对象,其实只能存在一个对象。这是小编自己的一些理解,如果有不恰当的地方,还请指出!!


相关文章
|
4月前
|
设计模式 安全 NoSQL
Java面试题:设计一个线程安全的单例模式,并解释其内存占用和垃圾回收机制;使用生产者消费者模式实现一个并发安全的队列;设计一个支持高并发的分布式锁
Java面试题:设计一个线程安全的单例模式,并解释其内存占用和垃圾回收机制;使用生产者消费者模式实现一个并发安全的队列;设计一个支持高并发的分布式锁
64 0
|
4月前
|
设计模式 安全 Java
Java面试题:如何实现一个线程安全的单例模式,并确保其在高并发环境下的内存管理效率?如何使用CyclicBarrier来实现一个多阶段的数据处理任务,确保所有阶段的数据一致性?
Java面试题:如何实现一个线程安全的单例模式,并确保其在高并发环境下的内存管理效率?如何使用CyclicBarrier来实现一个多阶段的数据处理任务,确保所有阶段的数据一致性?
56 0
|
数据库
易搭工作流引擎用是什么开源 还是阿里自研产品,零代码平台场景页面映射数据库表是动态创建,采用什么框架处理,怎么让系统产生高并发能力。易搭权限有没有了解,求解。
易搭工作流引擎用是什么开源 还是阿里自研产品,零代码平台场景页面映射数据库表是动态创建,采用什么框架处理,怎么让系统产生高并发能力。易搭权限有没有了解,求解。
|
设计模式 安全 Java
【Java|多线程与高并发】设计模式-单例模式(饿汉式,懒汉式和静态内部类)
设计模式是一种在软件开发中常用的解决复杂问题的方法论。它提供了一套经过验证的解决方案,用于解决特定类型问题的设计和实现。设计模式可以帮助开发人员提高代码的可重用性、可维护性和可扩展性。
|
SQL Java
解决单例模式中懒汉式不支持高并发,饿汉式不支持懒加载问题最简单方法——基于枚举类型的单例实现
解决单例模式中懒汉式不支持高并发,饿汉式不支持懒加载问题最简单方法——基于枚举类型的单例实现
161 0
解决单例模式中懒汉式不支持高并发,饿汉式不支持懒加载问题最简单方法——基于枚举类型的单例实现
|
SQL Java
DCL(Double Check Lock双重检锁机制)解决单例模式中懒汉式不支持高并发,饿汉式不支持懒加载问题
DCL(Double Check Lock双重检锁机制)解决单例模式中懒汉式不支持高并发,饿汉式不支持懒加载问题
206 0
DCL(Double Check Lock双重检锁机制)解决单例模式中懒汉式不支持高并发,饿汉式不支持懒加载问题
|
存储 canal 缓存
【高并发项目实战】千万级并发的购物车系统设计与代码详解
本文主要介绍redis在千万级系统中设计架构方案,如何在设计上抛弃mysql,主架构设计、缓存一致性方案、大value处理方案和redis限流和故障恢复降级方案设计与代码详解
|
Java 测试技术 微服务
为什么我建议线上高并发量的日志输出的时候不能带有代码位置(下)
为什么我建议线上高并发量的日志输出的时候不能带有代码位置(下)
为什么我建议线上高并发量的日志输出的时候不能带有代码位置(下)
|
算法 Java 微服务
为什么我建议线上高并发量的日志输出的时候不能带有代码位置(上)
为什么我建议线上高并发量的日志输出的时候不能带有代码位置(上)
为什么我建议线上高并发量的日志输出的时候不能带有代码位置(上)