DCL(Double Check Lock双重检锁机制)解决单例模式中懒汉式不支持高并发,饿汉式不支持懒加载问题

简介: DCL(Double Check Lock双重检锁机制)解决单例模式中懒汉式不支持高并发,饿汉式不支持懒加载问题

DCL(Double Check Lock双重检锁机制)解决单例模式中懒汉式不支持高并发,饿汉式不支持懒加载问题


一、前言

我们在使用单例模式时,一般有两种选择,一个是懒汉式,一个是饿汉式。但是这两种都是有各自的缺点,无法满足我们的需求,所以DCL(Double Check Lock双端检锁机制)出现了,一种既支持延迟加载、又支持高并发的单例实现方式。

如果不清楚懒汉式为什么不支持高并发可以看一下这篇文章—>

单例模式的懒汉模式为什么在高并发中会出现问题

其他解决方案—>


静态内部类解决单例模式中懒汉式不支持高并发,饿汉式不支持懒加载问题


利用枚举特性解决单例模式中懒汉式不支持高并发,饿汉式不支持懒加载问题


二、具体实现

- DCL单例模式

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){
            synchronized(Phone.class) { // 此处为类级别的锁
               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对象被 new 出来,并且赋值给 phone之后,还没来得及初始化(执行构造函数中的代码逻辑),就被另一个线程使用了。要解决这个问题,我们需要给 phone成员变量加上 volatile 关键字,禁止指令重排序才行。实际上,只有很低版本的 Java 才会有这个问题。我们现在用的高版本的 Java 已经在 JDK 内部实现中解决了这个问题(解决的方法很简单,只要把对象 new 操作和初始化操作设计为原子操作,就自然能禁止重排序)。

本段话来自极客时间王老师

相关文章
|
4月前
|
设计模式 安全 NoSQL
Java面试题:设计一个线程安全的单例模式,并解释其内存占用和垃圾回收机制;使用生产者消费者模式实现一个并发安全的队列;设计一个支持高并发的分布式锁
Java面试题:设计一个线程安全的单例模式,并解释其内存占用和垃圾回收机制;使用生产者消费者模式实现一个并发安全的队列;设计一个支持高并发的分布式锁
64 0
|
4月前
|
设计模式 安全 Java
Java面试题:如何实现一个线程安全的单例模式,并确保其在高并发环境下的内存管理效率?如何使用CyclicBarrier来实现一个多阶段的数据处理任务,确保所有阶段的数据一致性?
Java面试题:如何实现一个线程安全的单例模式,并确保其在高并发环境下的内存管理效率?如何使用CyclicBarrier来实现一个多阶段的数据处理任务,确保所有阶段的数据一致性?
56 0
|
设计模式 安全 Java
【Java|多线程与高并发】设计模式-单例模式(饿汉式,懒汉式和静态内部类)
设计模式是一种在软件开发中常用的解决复杂问题的方法论。它提供了一套经过验证的解决方案,用于解决特定类型问题的设计和实现。设计模式可以帮助开发人员提高代码的可重用性、可维护性和可扩展性。
|
SQL Java
解决单例模式中懒汉式不支持高并发,饿汉式不支持懒加载问题最简单方法——基于枚举类型的单例实现
解决单例模式中懒汉式不支持高并发,饿汉式不支持懒加载问题最简单方法——基于枚举类型的单例实现
161 0
解决单例模式中懒汉式不支持高并发,饿汉式不支持懒加载问题最简单方法——基于枚举类型的单例实现
|
设计模式
单例模式的懒汉模式为什么在高并发中会出现问题?一个代码例子告诉你
单例模式的懒汉模式为什么在高并发中会出现问题?一个代码例子告诉你
100 0
单例模式的懒汉模式为什么在高并发中会出现问题?一个代码例子告诉你
|
Dubbo 应用服务中间件
Dubbo源码Debug-Double Check考点
![image.png](https://ata2-img.cn-hangzhou.oss-pub.aliyun-inc.com/76230c3baf735828dedd39eca3c4d015.png) 说说看,你觉得这个在多线程并发的情况下会有问题吗? ![image.png](https://ata2-img.cn-hangzhou.oss-pub.aliyun-inc.com/
470 0
|
测试技术
《设计模式》学习笔记5——单例模式【高并发拓展】
定义 单例模式又称为单件模式,这个模式大概是设计模式中最好理解的了,我起初就打算从这里开始学,甚至还记过另一篇单例模式学习的笔记。 但是之后跟着《设计模式》这本书系统的学,就索性从第一页开始,而单例模式算是复习,也算是再深入的理解一次。
2067 0
|
6月前
|
消息中间件 Java Linux
2024年最全BATJ真题突击:Java基础+JVM+分布式高并发+网络编程+Linux(1),2024年最新意外的惊喜
2024年最全BATJ真题突击:Java基础+JVM+分布式高并发+网络编程+Linux(1),2024年最新意外的惊喜
|
5月前
|
缓存 NoSQL Java
Java高并发实战:利用线程池和Redis实现高效数据入库
Java高并发实战:利用线程池和Redis实现高效数据入库
477 0
|
3月前
|
监控 算法 Java
企业应用面临高并发等挑战,优化Java后台系统性能至关重要
随着互联网技术的发展,企业应用面临高并发等挑战,优化Java后台系统性能至关重要。本文提供三大技巧:1)优化JVM,如选用合适版本(如OpenJDK 11)、调整参数(如使用G1垃圾收集器)及监控性能;2)优化代码与算法,减少对象创建、合理使用集合及采用高效算法(如快速排序);3)数据库优化,包括索引、查询及分页策略改进,全面提升系统效能。
45 0