一单例模式(Singleton)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一单例模式(Singleton)相关的知识,希望对你有一定的参考价值。

单例模式最初的定义出现于《设计模式》(艾迪生维斯理, 1994):“保证一个类仅有一个实例,并提供一个访问它的全局访问点。”

 

特点:一是某个类只能有一个实例;

        二是它必须自行创建这个实例;

        三是它必须自行向整个系统提供这个实例。

 

一、经典实现

using System;

namespace SingletonPattern
{
    // 经典写法
    // sealed 阻止其他类从该类继承
    public sealed class ClassicalSample
    {
        // 用来保存唯一实例
        private static ClassicalSample _classicalSample;
        // 锁范围
        private static readonly object obj = new object();

        // 私有构造函数,阻止外部new实例化
        private ClassicalSample()
        {
            Console.WriteLine("实例化");
        }

        // 统一该类的
        public static ClassicalSample GetInstance()
        {
            // 减少锁的开销
            if (_classicalSample == null)
            {
                // 防止多线程并发
                lock (obj)
                {
                    // 
                    if (_classicalSample == null)
                    {
                        _classicalSample = new ClassicalSample();
                    }
                }
            }

            Console.WriteLine("获取实例");

            return _classicalSample;
        }
    }
}

二、静态构造函数实现

using System;

namespace SingletonPattern
{
    public sealed class StaticConstructorSample
    {
        private static StaticConstructorSample _staticConstructorSample;

        private StaticConstructorSample()
        {
            Console.WriteLine("实例化");
        }

        // 静态构造函数:第一次使用的时候执行,且只执行一次
        static StaticConstructorSample()
        {
            _staticConstructorSample = new StaticConstructorSample();
            Console.WriteLine("静态构造函数实例化");
        }

        public static StaticConstructorSample GetInstance()
        {
            Console.WriteLine("获取实例");
            return _staticConstructorSample;
        }
    }
}

三、静态变量实现

using System;

namespace SingletonPattern
{
    public sealed class StaticVariableSample
    {
        private static readonly StaticVariableSample _StaticVariableSample = new StaticVariableSample();

        private StaticVariableSample()
        {
            Console.WriteLine("实例化");
        }

        public static StaticVariableSample GetInstance()
        {
            Console.WriteLine("获取实例");
            return _StaticVariableSample;
        }
    }
}

 测试:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace SingletonPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            ClassicalSampleTest();

            StaticConstructorSampleTest();

            StaticVariableSampleTest();

            Console.Read();
        }

        static void ClassicalSampleTest()
        {
            Console.WriteLine("经典单例模式测试");

            TaskFactory taskFactory = new TaskFactory();

            // 多线程测试的task组
            List<Task> tasks = new List<Task>();
            // 每个线程获取实例集
            List<ClassicalSample> list = new List<ClassicalSample>();

            for (int i = 0; i < 60; i++)
            {
                tasks.Add(taskFactory.StartNew<ClassicalSample>(() => ClassicalSample.GetInstance()).ContinueWith((r) =>
                {
                    list.Add(r.Result);
                }));
            }

            taskFactory.ContinueWhenAll(tasks.ToArray(), p =>
            {
                Console.WriteLine("");
                Console.WriteLine("tasks组执行完成之后一共获取了{0}次实例", p.Count());

                Console.WriteLine("实例个数{0}", list.Distinct().Count());
            });
        }

        static void StaticConstructorSampleTest()
        {
            Console.WriteLine("静态构造函数单例模式测试");

            TaskFactory taskFactory = new TaskFactory();

            // 多线程测试的task组
            List<Task> tasks = new List<Task>();
            // 每个线程获取实例集
            List<StaticConstructorSample> list = new List<StaticConstructorSample>();

            for (int i = 0; i < 60; i++)
            {
                tasks.Add(taskFactory.StartNew<StaticConstructorSample>(() => StaticConstructorSample.GetInstance()).ContinueWith((r) =>
                {
                    list.Add(r.Result);
                }));
            }

            taskFactory.ContinueWhenAll(tasks.ToArray(), p =>
            {
                Console.WriteLine("");
                Console.WriteLine("tasks组执行完成之后一共获取了{0}次实例", p.Count());

                Console.WriteLine("实例个数{0}", list.Distinct().Count());
            });
        }

        static void StaticVariableSampleTest()
        {
            Console.WriteLine("静态变量单例模式测试");

            TaskFactory taskFactory = new TaskFactory();


            // 多线程测试的task组
            List<Task> tasks = new List<Task>();
            // 每个线程获取实例集
            List<StaticVariableSample> list = new List<StaticVariableSample>();

            for (int i = 0; i < 60; i++)
            {
                tasks.Add(taskFactory.StartNew(() => StaticVariableSample.GetInstance()).ContinueWith((r) =>
                {
                    list.Add(r.Result);
                }));
            }

            taskFactory.ContinueWhenAll(tasks.ToArray(), p =>
            {
                Console.WriteLine("");
                Console.WriteLine("tasks组执行完成之后一共获取了{0}次实例", p.Count());

                Console.WriteLine("实例个数{0}", list.Distinct().Count());
            });
        }
    }
}

 

以上是关于一单例模式(Singleton)的主要内容,如果未能解决你的问题,请参考以下文章

Android框架设计模式——Singleton Method

Singleton Pattern (单例模式)

05-单例(Singleton)模式Ruby实现

浅谈JAVA设计模式之——单例模式(Singleton)

C++之单例(singleton)模式

Java面向对象--单例(Singleton)设计模式和main方法