前言
设计模式的文章很多,所以此文章只是为了巩固一下自己的基础,说的不详细请见谅。
介绍 - 单例模式
官方定义:确保一个类只有一个实例,并提供一个全局访问点。
通俗定义:就是一个类只有一个单个实例。(也没啥区别)
实现
如何保证一个类只有一个实例呢?
1. 首先一个类是如何创建实例的? - 通过构造函数
2. 如何保证只创建一个呢? - 构造函数只执行一次
3. 如何保证构造函数只执行一次呢? - 访问外部类无权访问
4. 如何让访问外部类无权访问? - 私有方法
问题解决,上代码:
/// <summary>
/// 单例类
/// </summary>
public class Singleton
{
/// <summary>
/// 私有构造函数
/// </summary>
private Singleton() { }
/// <summary>
/// 单例字段
/// </summary>
private static Singleton _instance;
/// <summary>
/// 单例对象
/// </summary>
public static Singleton Instance
{
get
{
if (_instance == null)
_instance = new Singleton();
return _instance;
}
} /// <summary>
/// 输出
/// </summary>
public void WriteLine()
{
Console.WriteLine("哈希Code : " + this.GetHashCode());
}
}
测试输出 HashCode :
class Program
{
static void Main(string[] args)
{
Singleton.Instance.WriteLine();
Singleton.Instance.WriteLine();
Singleton.Instance.WriteLine();
Console.Read();
}
}
结果:
这样就结束了吗? -(身为C#老鸟的我还要考虑下线程安全的问题,考虑并发的情况)
我们需要构建一个并发的情形及多条线程同时创建对象,下面我就用简单粗暴的方法,需要对单例进行修改:
/// <summary>
/// 单例对象
/// </summary>
public static Singleton Instance
{
get
{
if (_instance == null)
{
Thread.Sleep();
_instance = new Singleton();
}
return _instance;
}
}
调用测试:
class Program
{
static void Main(string[] args)
{
//线程1
Thread thread1 = new Thread(new ThreadStart(() =>
{
Singleton.Instance.WriteLine();
}));
//线程2
Thread thread2 = new Thread(new ThreadStart(() =>
{
Singleton.Instance.WriteLine();
}));
//线程3
Thread thread3 = new Thread(new ThreadStart(() =>
{
Singleton.Instance.WriteLine();
}));
thread1.Start();
thread2.Start();
thread3.Start();
Console.Read();
}
}
输出结果:
所以我们要对代码进行改进(加锁):
/// <summary>
/// 单例类
/// </summary>
public class Singleton
{
/// <summary>
/// 锁
/// </summary>
private static object locker = new object();
/// <summary>
/// 私有构造函数
/// </summary>
private Singleton() { }
/// <summary>
/// 单例字段
/// </summary>
private static Singleton _instance;
/// <summary>
/// 单例对象
/// </summary>
public static Singleton Instance
{
get
{
lock (locker)
{
if (_instance == null)
{
Thread.Sleep();
_instance = new Singleton();
}
}
return _instance;
}
} /// <summary>
/// 输出
/// </summary>
public void WriteLine()
{
Console.WriteLine("哈希Code : " + this.GetHashCode());
}
}
测试结果:
解决!
锁是个好东西但是要慎用,它是很耗资源的。所以还需要对代码进行改进,看代码我们知道只有 _instance 为 null 时才需要考虑并发加锁,所以我们再次改进:
/// <summary>
/// 单例类
/// </summary>
public class Singleton
{
/// <summary>
/// 锁
/// </summary>
private static object locker = new object();
/// <summary>
/// 私有构造函数
/// </summary>
private Singleton() { }
/// <summary>
/// 单例字段
/// </summary>
private static Singleton _instance;
/// <summary>
/// 单例对象
/// </summary>
public static Singleton Instance
{
get
{
if(_instance == null)
{
lock (locker)
{
if (_instance == null)
{
Thread.Sleep();
_instance = new Singleton();
}
}
}
return _instance;
}
} /// <summary>
/// 输出
/// </summary>
public void WriteLine()
{
Console.WriteLine("哈希Code : " + this.GetHashCode());
}
}
欢迎批评指正!转载请注明出处:http://www.cnblogs.com/xinwang/p/6294784.html