为了节约系统资源,有时需要确保系统中某个类只有唯一一个实例,当这个唯一实例创建成功之后,我们无法再创建一个同类型的其他对象,所有的操作都只能基于这个唯一实例。为了确保对象的唯一性,我们可以通过单例模式来实现,这就是单例模式的动机所在。
单例的懒汉式和饿汉式
懒汉式
/// <summary>
/// Class VideoPrompt
/// </summary>
public class VideoPrompt:INotifyPropertyChanged
{
private int a = -1;
/// <summary>
/// The instance
/// </summary>
private static VideoPrompt mInstance;
/// <summary>
/// The lock object
/// </summary>
private static object mLockObject = new object();
/// <summary>
/// Gets the instance.
/// </summary>
/// <value>The instance.</value>
public static VideoPrompt Instance
{
get
{
if (mInstance == null)
{
lock (mLockObject)
{
if (mInstance == null)
{
mInstance = new VideoPrompt();
}
}
}
return mInstance;
}
}
/// <summary>
/// The info text
/// </summary>
private string mInfoText;
/// <summary>
/// Gets or sets the info text.
/// </summary>
/// <value>The info text.</value>
public string InfoText
{
get { return mInfoText; }
set
{
if (mInfoText != value)
{
mInfoText = value;
OnpropertyChanged("InfoText");
}
}
}
/// <summary>
/// Sets the binding.
/// </summary>
/// <param name="dialog">The dialog.</param>
public void SetBinding(CancelDialog dialog)
{
Binding bind = new Binding("InfoText");
bind.Mode = BindingMode.TwoWay;
bind.Source = Instance;
bind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
dialog.SetBinding(OkCancelDialog.InfoTextProperty, bind);
}
#region INotifyPropertyChanged Members
/// <summary>
/// Occurs when a property value changes.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Called when [changed].
/// </summary>
/// <param name="propertyName">Name of the property.</param>
private void OnpropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
为什么要加双重判断
双重检查锁定中,当实例不存在且同时有两个线程调用属性时,它们都可以通过第一重“instance==null”判断,然后由于lock锁定机制,只有一个线程进入lock中执行创建代码,另一个线程处于排队等待状态,必须等待第一个线程执行完毕后才可以进入lock锁定的代码,如果此时不进行第二重“instance==null”判断,第二个线程并不知道实例已经创建,将继续创建新的实例,还是会产生多个单例对象,违背单例模式的设计思想,因此需要进行双重检查。
饿汉式代码
class Class1
{
private static Class1 mInstance = new Class1();
public Class1 Instance
{
get
{
return mInstance;
}
}
}
饿汉式单例类与懒汉式单例类比较
饿汉式单例类在类被加载时就将自己实例化,它的优点在于无须考虑多个线程同时访问的问题,可以确保实例的唯一性;从调用速度和反应时间角度来讲,由于单例对象一开始就得以创建,因此要优于懒汉式单例。但是无论系统在运行时是否需要使用该单例对象,由于在类加载时该对象就需要创建,因此从资源利用效率角度来讲,饿汉式单例不及懒汉式单例,而且在系统加载时由于需要创建饿汉式单例对象,加载时间可能会比较长。
懒汉式单例类在第一次使用时创建,无须一直占用系统资源,实现了延迟加载,但是必须处理好多个线程同时访问的问题,特别是当单例类作为资源控制器,在实例化时必然涉及资源初始化,而资源初始化很有可能耗费大量时间,这意味着出现多线程同时首次引用此类的机率变得较大,需要通过双重检查锁定等机制进行控制,这将导致系统性能受到一定影响。
}
}
单例模式与静态方法的区别
单例模式更符合面向对象的设计,可以把类的优势体现出来,如可以有自己的数据,可以实现接口,可以继承
,可以多态