版本一:

/// <summary>
/// A simple singleton class implements.
/// </summary>
public sealed class Singleton
{
    private static Singleton _instance = null;

/// <summary>
    /// Prevents a default instance of the
    /// <see cref="Singleton"/> class from being created.
    /// </summary>
    private Singleton()
    {
    }

/// <summary>
    /// Gets the instance.
    /// </summary>
    public static Singleton Instance
    {
        get { return _instance ?? (_instance = new Singleton()); }
    }
}

以上的实现方式适用于单线程环境,因为在多线程的环境下有可能得到Singleton类的多个实例。假如同时有两个线程去判断

(null == _singleton),并且得到的结果为真,那么两个线程都会创建类Singleton的实例,这样就违背了Singleton模式“唯一实例”的初衷。

版本二:

/// <summary>
/// A thread-safe singleton class.
/// </summary>
public sealed class Singleton
{
private static Singleton _instance = null;
private static readonly object SynObject = new object(); Singleton()
{
} /// <summary>
/// Gets the instance.
/// </summary>
public static Singleton Instance
{
get
{
// Syn operation.
lock (SynObject)
{
return _instance ?? (_instance = new Singleton());
}
}
}
}

以上方式的实现方式是线程安全的,首先我们创建了一个静态只读的进程辅助对象,由于lock是确保当一个线程位于代码的临界区时,另一个线程不能进入临界区(同步操作)。如果其他线程试图进入锁定的代码,则它将一直等待,直到该对象被释放。从而确保在多线程下不会创建多个对象实例了。只是这种实现方式要进行同步操作,这将是影响系统性能的瓶颈和增加了额外的开销。

版本三:

/// <summary>
/// Double-Checked Locking implements a thread-safe singleton class
/// </summary>
public sealed class Singleton
{
    private static Singleton _instance = null;
    // Creates an syn object.
    private static readonly object SynObject = new object();

Singleton()
    {
    }

public static Singleton Instance
    {
        get
        {
            // Double-Checked Locking
            if (null == _instance)
            {
                lock (SynObject)
                {
                    if (null == _instance)
                    {
                        _instance = new Singleton();
                    }
                }
            }
            return _instance;
        }
    }
}

版本四:经典模式

public class Singleton
{
        private static Singleton instance;

private Singleton()
        {
       
        }

public static Singleton GetInstance()
        {
                if(instance==null)
                {
                        instance=new Singleton();
                }
                return instance;
        }
}

  解析如下:

  1)首先,该Singleton的构造函数必须是私有的,以保证客户程序不会通过new()操作产生一个实例,达到实现单例的目的;

  2)因为静态变量的生命周期跟整个应用程序的生命周期是一样的,所以可以定义一个私有的静态全局变量instance来保存该类的唯一实例;

  3)必须提供一个全局函数访问获得该实例,并且在该函数提供控制实例数量的功能,即通过if语句判断instance是否已被实例化,如果没有则可以同new()创建一个实例;否则,直接向客户返回一个实例。

  在这种经典模式下,没有考虑线程并发获取实例问题,即可能出现两个线程同时获取instance实例,且此时其为null时,就会出现两个线程分别创建了instance,违反了单例规则。因此,需对上面代码修改。

版本五:

public class Singleton
{
       private static Singleton instance;
       private static object _lock=new object();

private Singleton()
       {

}

public static Singleton GetInstance()
       {
               if(instance==null)
               {
                      lock(_lock)
                      {
                             if(instance==null)
{
                                     instance=new Singleton();
                             }
                      }
               }
               return instance;
       }
}

上述代码使用了双重锁方式较好地解决了多线程下的单例模式实现。先看内层的if语句块,使用这个语句块时,先进行加锁操作,保证只有一个线程可以访问该语句块,进而保证只创建了一个实例。再看外层的if语句块,这使得每个线程欲获取实例时不必每次都得加锁,因为只有实例为空时(即需要创建一个实例),才需加锁创建,若果已存在一个实例,就直接返回该实例,节省了性能开销。

版本六:饿汉模式

public sealed class Singleton
{
        private static readonly Singleton instance=new Singleton();

private Singleton()
        {
        }

public static Singleton GetInstance()
        {
               return instance;
        }
}

版本七:延迟初始化

/// <summary>
/// Delaies initialization.
/// </summary>
public sealed class Singleton
{
    private Singleton()
    {
    }

/// <summary>
    /// Gets the instance.
    /// </summary>
    public static Singleton Instance { get { return Nested._instance; } }

private class Nested
    {
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static Nested()
        {
        }

internal static readonly Singleton _instance = new Singleton();
    }
}

版本八:静态初始化

public sealed class Singleton
{
    private static readonly Singleton _instance = new Singleton();

// Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static Singleton()
    {
    }

/// <summary>
    /// Prevents a default instance of the
    /// <see cref="Singleton"/> class from being created.
    /// </summary>
    private Singleton()
    {
    }

/// <summary>
    /// Gets the instance.
    /// </summary>
    public static Singleton Instance
    {
        get
        {
            return _instance;
        }
    }
}

WPFの单例模式的更多相关文章

  1. wpf 单例模式和异常处理 (原发布 csdn 2017-04-12 20:34:12)

    第一次写博客,如有错误,请大家及时告知,本人立即改之. 如果您有好的想法或者建议,我随时与我联系. 如果发现代码有误导时,请与我联系,我立即改之. 好了不多说,直接贴代码. 一般的错误,使用下面三个就 ...

  2. wpf1

    emCombobox.Items[2].IsEnabled = false; 隐藏下拉框里面的一个item wpf 单例模式. [DllImport("user32", CharS ...

  3. WPF使用Microsoft.VisualBasic创建单例模式引起的权限降低问题

    在进行WPF开发时,总是在找更加优雅去写单例模式的代码. 很多人都喜欢用Mutex,一个App.cs下很多的Mutex,我也喜欢用. 看完<WPF编程宝典>的第七章Applicaton类后 ...

  4. 年度巨献-WPF项目开发过程中WPF小知识点汇总(原创+摘抄)

    WPF中Style的使用 Styel在英文中解释为”样式“,在Web开发中,css为层叠样式表,自从.net3.0推出WPF以来,WPF也有样式一说,通过设置样式,使其WPF控件外观更加美化同时减少了 ...

  5. WPF入门教程系列四——Dispatcher介绍

    一.Dispatcher介绍 微软在WPF引入了Dispatcher,那么这个Dispatcher的主要作用是什么呢? 不管是WinForm应用程序还是WPF应用程序,实际上都是一个进程,一个进程可以 ...

  6. 16、WPF中的命令

    一.前言 事件的作用是发布.传播一些信息,消息送达接收者,事件的使命就算完成了,至于如何响应事件送来的消息事件并不做规定,每个接收者可以使用自己的行为来响应事件,也就是说事件不具有约束力.命令能够在代 ...

  7. WPF基础到企业应用系列7——深入剖析依赖属性(WPF/Silverlight核心)

    一. 摘要 首先圣殿骑士非常高兴这个系列能得到大家的关注和支持.这个系列从七月份開始到如今才第七篇,上一篇公布是在8月2日,掐指一算有二十多天没有继续更新了,最主要原因一来是想把它写好,二来是由于近期 ...

  8. WPF 10天修炼 第三天- Application全局应用程序类

    Application对象 当一个WPF应用程序启动时,首先会实例化一个全局唯一的Application对象,类似于WinForm下的Application类,用于控制整个应用程序,该类将用于追踪应用 ...

  9. WPF实现主题更换的简单DEMO

    WPF实现主题更换的简单DEMO 实现主题更换功能主要是三个知识点: 动态资源 ( DynamicResource ) INotifyPropertyChanged 接口 界面元素与数据模型的绑定 ( ...

随机推荐

  1. Spring之我见

    Spring 是什么(1) •Spring 是一个开源框架. •Spring 为简化企业级应用开发而生. 使用 Spring 可以使简单的 JavaBean 实现以前只有 EJB 才能实现的功能. • ...

  2. Windows 服务入门指南

    有很多时候,我们需要创建Windows Service. 这篇文章可以算是一个入门指南吧,希望对初学者有帮助. 要创建Windows Service, 首先选择Windows服务项目,如下图: 这里我 ...

  3. Dreamweaver 时间轴如何打开

    因为下午要辅导几个调皮捣蛋的小孩HTML, 什么能让他们感觉又简单又好玩而起又能提高他们的兴趣呢?DW中设置浮动广告吧!       想好了,动手去做.DwearmWeaver里面居然没了时间轴, 度 ...

  4. mtk的安卓手机刷机时出现的错误信息

    手机已成砖,用过好多工具都没刷回来,以下是用smart phone flash tool刷机时出现的错误信息 ---------------------------Smart Phone Flash ...

  5. yii2 render和renderPartial区别

    1.render()方法使用到项目中的布局layout,renderPartial()不使用布局

  6. 小结 javascript中的类型检测

    先吐槽一下博客园的编辑器,太不好用了,一旦粘贴个表格进来就会卡死,每次都要用html编辑器写,不爽! 关于javascript的类型检测,早在实习的时候就应该总结,一直拖到现在,当时因为这个问题还出了 ...

  7. 161118、linux(centos) 项目部署阶段相关命令汇总

    1.ssh免密码登陆 主要命令 cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys-->添加公钥 service sshd restart ...

  8. scala特质

    package com.ming.test /** * scala 特质,类似与java接口,但是比java接口强大,可以有实现方法,定义字段之类的 */ /** * 定义一个日志的特质 */ tra ...

  9. 使用Perl5获取有道词典释义

    Get Word Definition from dict.youda.com via Perl Script 获取基本释义 Get Basic Definition http://dict.youd ...

  10. wghd的git代码仓库分支管理说明【转】

    英文原文:http://www.nvie.com/posts/a-successful-git-branching-model/ 原文作者:Vincent Driessen 本文经Linux大棚博主总 ...