美文网首页
单例模式的线程安全性

单例模式的线程安全性

作者: Tiny荣 | 来源:发表于2019-04-28 21:17 被阅读0次

普通的单例模式是线程不安全的,验证方法如下:

```

sealed class Singleton1

    {

        private Singleton1()

        {

        }

        private static Singleton1 instance = null;

        public static Singleton1 Instance

        {

            get

            {

                if (instance == null)

                {

                    Console.WriteLine("Cup");

                    instance = new Singleton1();

                }

                return instance;

            }

        }

    }

class Program

    {

        static void Main(string[] args)

        {

            Singleton1 st1 = null;

            Singleton1 st2 = null;

            while (true)

            {

                Thread t1 = new Thread(() =>

                {

                    st1 = Singleton1.Instance;

                });

                Thread t2 = new Thread(() =>

                {

                    st2 = Singleton1.Instance;

                });

                t1.Start();

                t2.Start();

                Thread.Sleep(100);

            }

        }

    }

```

如上所示,打印的结果有很大概率出现两次"Cup",说明两个线程都创建了新的对象,单例被打破了。

改进方式:加锁

```

sealed class Singleton1

    {

        private Singleton1()

        {

        }

        private static readonly object syncObj = new object();

        private static Singleton1 instance = null;

        public static Singleton1 Instance

        {

            get

            {

                lock (syncObj)

                {

                    if (instance == null)

                    {

                        Console.WriteLine("Cup");

                        instance = new Singleton1();

                    }

                }

                return instance;

            }

        }

        public void Clear()

        {

            instance = null;

        }

    }

```

运行结果只有一个"Cup",程序在进入代码段时首先判断有没有加锁,如果没有就加锁,另一个线程判断代码已经有锁了,就直接返回,从而保证了单例的唯一性。

缺点:判断锁状态和尝试加锁操作比较消耗性能

改进:锁前判断:

```

public static Singleton1 Instance

        {

            get

            {

                if (instance == null)

                {

                    lock (syncObj)

                    {

                        if (instance == null)

                        {

                            Console.WriteLine("Cup");

                            instance = new Singleton1();

                        }

                    }

                }

                return instance;

            }

        }

```

如此,就只有第一次试图创建实例时要加锁

有没有不用锁的办法呢,也有:

```

sealed class Singleton1

    {

        private Singleton1()

        {

        }

        private static Singleton1 instance = new Singleton1();

        public static Singleton1 Instance

        {

            get

            {

                if (instance != null)

                {

                    return instance;

                }

                else

                {

                    return null;

                }

            }

        }

    }

```

C#在调用静态构造函数时初始化静态变量,运行时能够确保只调用一次静态构造函数。但这种机制不确定在其他语言中也存在

如果局限于C#中,还有更优化的方法:

```

sealed class Singleton1

    {

        private Singleton1()

        {

        }

        public static Singleton1 Instance

        {

            get

            {

                return Nested.instance;

            }

        }

        class Nested

        {

            static Nested()

            {

            }

            internal static readonly Singleton1 instance = new Singleton1();

        }

    }

```

将创建实例的时机局限在获取Instance时。

相关文章

  • Double Check Lock是存在问题的

    Double Check Lock 上述代码,能保证单例方式的线程安全性吗? 答案是肯定的。它既能实现单例模式,又...

  • Java Singleton 单例模式

    单例模式 属于创建型模式 自行完成实例化,私有化构造函数 单例模式的目标 实例唯一性 线程安全性 任何情况都需要确...

  • C++设计模式

    单例 单例模式的一种实现(《Effective C++》) 此处是通过C++11新的语义来保证线程的安全性,具体由...

  • 单例模式

    单例模式保证全局唯一性,得考虑线程安全性延迟加载? 饿汉模式 线程安全的,但是不支持延迟加载(有问题早发现)① /...

  • 聊聊Kotlin单例,从object单例,到带参数单例,论如何优

    一. 序 单例模式是我们在日常编程中,比较常用的设计模式。一个好的单例,必然需要满足唯一性和线程安全性。而 Jav...

  • 单例模式Java篇

    单例设计模式- 饿汉式 单例设计模式 - 懒汉式 单例设计模式 - 懒汉式 - 多线程并发 单例设计模式 - 懒汉...

  • 设计模式

    手写单例模式(线程安全) 你知道几种设计模式?单例模式是什么?Spring中怎么实现单例模式?

  • 单例模式-Java

    饿汉、懒汉、双重校验锁及其修正、静态内部类、枚举,线程安全性以及原因 单例模式有以下特点: 1、单例类只能有一个实...

  • 设计模式(2) 单例模式

    单例模式 线程安全的Singleton 会破坏Singleton的情况 线程级Singleton 单例模式是几个创...

  • 单例模式

    单例模式介绍 把单例模式放到多线程基础这块,是因为单例和多线程有一点的关系。何为单例模式? 在它的核心结构中只包含...

网友评论

      本文标题:单例模式的线程安全性

      本文链接:https://www.haomeiwen.com/subject/rehsnqtx.html