用两个小例子来解释单例模式中的“双重锁定”

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/details/26397949

学习单例模式时,好多人都不太理解双重锁定。学完后突然想到一个很有趣的例子。

       单例模式结构图:

        代码:

        Singleton类

    class Singleton
    {
        private static Singleton instance;
        private static readonly object syncRoot = new object();  //程序运行时创建一个静态只读的进程辅助对象
        private Singleton() { }                 //用private修饰构造方法,防止外界利用new创建此类实例
        public static Singleton GetInstance()
        {
            if (instance == null)               //若instance对象为null,则继续
            {
                lock (syncRoot)                 //↓↓↓↓在同一时刻加了锁的这部分程序只有一个线程可以进入↓↓↓↓
                {
                    if (instance == null)//如果instance对象为null,则为它分配实例
                    {
                        instance = new Singleton();
                    }
                }                               //↑↑↑↑在同一时刻加了锁的这部分程序只有一个线程可以进入↑↑↑↑
            } 
            return instance;
        }
    }

客户端代码

    static void Main(string[] args)
    {
        Singleton singleton1=Singleton.GetInstance();
        Singleton singleton2=Singleton.GetInstance();
        //……
    }

说明:

      《大话设计模式》中,小菜问道:“我在外面已经判断了instance实例是否存在,为什么在lock里面还要做一次instance实例是否存在的判断呢?”

       大鸟是这么回答的:当instance为null并且同时有两个线程调用GetInstance方法时,他们将都可以通过第一重instance==null的判断。然后由于lock机制,这两个线程则只有一个进入,另外一个在外排队等候,必须要其中的一个进入并出来后,另一个才能进入,而此时如果没有了第二重的instance是否为null的判断,则第一个线程创建了实例,第二个线程还是可以继续再创建新的实例,这就没有达到单例的目的。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏我的小碗汤

mysql大小写敏感与校对规则

模糊匹配 jg%,结果以JG开头的字符串也出现在结果集中,大家很自然的认为是大小写敏感的问题。那么mysql中大小写敏感是如何控制的;数据库名,表名,字段名这些...

2701
来自专栏大学生计算机视觉学习DeepLearning

c++ 网络编程(七)TCP/IP LINUX下 socket编程 基于套接字的标准I/O函数使用 与 fopen,feof,fgets,fputs函数用法

原文链接:https://www.cnblogs.com/DOMLX/p/9614820.html

2214
来自专栏python学习指南

Elasticsearch多索引

 在Elasticsearch中,一般的查询都支持多索引。 只有文档API或者别名API等不支持多索引操作,因此本篇就翻译一下多索引相关的内容。 首先,先...

5486
来自专栏JetpropelledSnake

SQL学习笔记之MySQL中真假“utf8” 问题

最近我遇到了一个 bug,我试着通过 Rails 在以“utf8”编码的 MariaDB 中保存一个 UTF-8 字符串,然后出现了一个离奇的错误:

872
来自专栏Dato

浅谈 Mybatis中的 ${ } 和 #{ }的区别

好了,真正做开发也差不多一年了。一直都是看别人的博客,自己懒得写,而且也不会写博客,今天就开始慢慢的练习一下写博客吧。前段时间刚好在公司遇到这样的问题。 一、举...

3489
来自专栏芋道源码1024

数据库中间件 MyCAT 源码解析 —— 分片结果合并(一)

1. 概述 相信很多同学看过 MySQL 各种优化的文章,里面 99% 会提到:单表数据量大了,需要进行分片(水平拆分 or 垂直拆分)。分片之后,业务上必然面...

45713
来自专栏osc同步分享

mybatis 的一些常用功能

1. association 查询结果的一对一关联: <resultMap id="blogResult" type="Blog"> <id propert...

2918
来自专栏黑泽君的专栏

day31_Hibernate复习_03(补刀)

731
来自专栏芋道源码1024

数据库分库分表中间件 Sharding-JDBC 源码分析 —— SQL 执行

本文主要基于 Sharding-JDBC 1.5.0 正式版 1. 概述 2. ExecutorEngine 2.1 ListeningExecutorServ...

3847
来自专栏芋道源码1024

【死磕Java并发】—–Java内存模型之从JMM角度分析DCL

DCL,即Double Check Lock,中卫双重检查锁定。其实DCL很多人在单例模式中用过,LZ面试人的时候也要他们写过,但是有很多人都会写错。他们为什么...

36912

扫码关注云+社区

领取腾讯云代金券