C#中单例模式的示例分析|c# 单例类

小编给大家分享一下C#中单例模式的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!单例模式的定义:确保一个类只有一个实例,并提供一个全局访问点。首先实例大家。

小编给大家分享一下C#中单例模式的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

单例模式的定义:

确保一个类只有一个实例,并提供一个全局访问点。

首先实例大家应该都明白就是类生成对象的过程简单的就是String s=new String(),则s就是个实例。

Q:如何只生成一个实例?

A:1)首先必须将构造函数变为私有从而防止其他类实例化,并且只能有一个构造函数。因为系统会默认一个无参构造函数,而且默认pubpc访问修饰符。 所以必须写一个私有无参让默认无效。(通常单例模式都是不带形参的)

2)在该类中声明一个自己本身的静态实例,然后通过静态方法返回。

Q:如何提供一个全局访问点?

A:在类中创建一个公共并且静态的属性。(因为静态方法是类中的一个成员方法,属于整个类,即不用创建任何对象也可以直接调用。单例模式是不允许其他类实例的。)

代码:

分为两种模式:

1.LAZY模式

就是延迟加载, 设计模式是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据(读取属性值)的时候,才真正执行数据加载操作.有效使用它可以大大提高系统性能。

2.饿汉模式

与LAZY模式相反 ,加载时会将自己实例化。起来最容易的单例模式。

分析代码1:(经典)

//不要用这种方式
pubpcsealedclassSingleton
{
privatestaticSingletoninstance=null;//声明自己本身的静态实例
privateSingleton(){}//私有构造
pubpcstaticSingletonInstance()//提供全局访问点
{
if(instance==null)//实例不存在则创建
{
instance=newSingleton();
}
returninstance;
}
}

该代码仅供理解,单例模式的定义。

问题:该方法是非线程安全的,当有两个线程同时进入时,如果instance为null则都会创建实例。实际上,在测试以前,实例就已经有可能被创建了,但是内存模型不能保证这个实例能被其他的线程看到。

下面我们优化改进

分析代码2:(非安全线程)

pubpcsealedclassSingleton
{
privatestaticSingletoninstance=null;
privatestaticreadonlyobjectpadlock=newobject();//定义一个标识确保线程同步
Singleton(){}
pubpcstaticSingletonInstance()
{
lock(padlock)//线程到达时加锁运行完之后解锁当遇到加锁线程就会挂起等待解锁
{
if(instance==null)
{
instance=newSingleton();
}
returninstance;
}
}
}

以上解决了多线程问题。

问题:性能上来说,锁变成了每次都必须的当这个实例被响应的时候。此时完全没必要对线程辅助对象加锁之后再去判断,所以上面的实现方式增加了额外的开销。

下面我们进行优化改进:

代码分析3:(双重锁定)

pubpcsealedclassSingleton
{
privatestaticSingletoninstance=null;
privatestaticreadonlyobjectpadlock=newobject();
Singleton(){}
pubpcstaticSingletonInstance
{
get
{
if(instance==null)//外层的if语句块,这使得每个线程欲获取实例时不必每次都得加锁,因为只有实例为空时(即需要创建一个实例),才需加锁创建
{
lock(padlock)
{
if(instance==null)
{
instance=newSingleton();
}
}
}
returninstance;
}
}
}

这种“双重检查锁定”理论上是完美的

问题是:并不能保证它会在单处理器或多处理器计算机上顺利运行。(反正就是有问题吧 之后再研读一下 看看具体是怎么回事)

代码分析4:(不完全LAZY)

pubpcsealedclassSingleton
{
privatestaticreadonlySingletoninstance=newSingleton();

//显示的static构造函数
//静态构造函数抑制了beforefieldinit特性(访问成员之前就执行静态函数)
staticSingleton(){}
privateSingleton(){}
pubpcstaticSingletonInstance
{
get
{
returninstance;
}
}
}

不完全LAZY模式(通过抑制beforefildinit特性并不能起到太大的效果)

代码分析5:(完全LAZY)

pubpcsealedclassSingleton
{
privateSingleton(){}
pubpcstaticSingletonInstance{get{returnNested.instance;}}
//嵌套类
privateclassNested
{
//抑制beforefieldinit特性
staticNested(){}
internalstaticreadonlySingletoninstance=newSingleton();
}
}

这里使用了嵌套类(嵌套类型是LAZY加载的,也就是说嵌套类型在使用他时才会初始化)

代码分析6:(Lazy<T>)

pubpcsealedclassSingleton
{
//使用.NET4Lazy<T>
privatestaticreadonlyLazy<Singleton>lazy=newLazy<Singleton>(()=>newSingleton());
pubpcstaticSingletonInstance{get{returnlazy.Value;}}
privateSingleton(){}
}

Lazy<T> 对象初始化默认是线程安全的,在多线程环境下,第一个访问 Lazy<T> 对象的 Value 属性的线程将初始化 Lazy<T> 对象,以后访问的线程都将使用第一次初始化的数据。

以上全部是LAZY模式,现在了解下饿汉模式

代码分析7:

pubpcsealedclassSingleton
{
privatestaticreadonlySingletoninstance=newSingleton();//直接实例化
privateSingleton(){}
pubpcstaticSingletonInstance()
{
returninstance;
}
}

在这种模式下,无需自己解决线程安全性问题,CLR会给我们解决。由此可以看到这个类被加载时,会自动实例化这个类,而不用在第一次调用Instance()后才实例化出唯一的单例对象。

为了优化系统当然还是选择优化模式。LAZY模式最好的应该是使用Lazy<T>简短安全。

以上是“C#中单例模式的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程行业资讯频道!

C#中单例模式的示例分析文章到此结束,字数约3674字,希望可以帮助到大家。屹东网往后会继续推荐C#中单例模式的示例分析相关内容。