有些类也需要计划生育——单例模式
2020/4/8 21:01:23
本文主要是介绍有些类也需要计划生育——单例模式,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
单例模式,保证一个类仅有一个实例,并提供一个访问它的全局访问点。
使用场景
通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象。一个最好的办法就是,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该实例的方法。
懒汉式单例类
懒汉式单例类,即要在第一次被引用时,才会将自己实例化。
比如,在主窗体上不同的2个按钮打开同一个工具窗口。
工具窗口类:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace ConsoleApp2 { public partial class FormToolbox : Form { private static FormToolbox ftb = null; //构造方法私有,外部代码不能直接new来实例化它 private FormToolbox() { InitializeComponent(); } public static FormToolbox GetInstance() { if (ftb == null || ftb.IsDisposed) { ftb = new FormToolbox(); ftb.MdiParent = Form1.ActiveForm; } return ftb; } private void FormToolbox_Load(object sender, EventArgs e) { } } }
主窗口类:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace ConsoleApp2 { public partial class Form1 : Form { FormToolbox formToolbox; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { this.IsMdiContainer = true; } private void ToolStripMenuItem_Click(object sender, EventArgs e) { FormToolbox.GetInstance().Show(); } private void toolStripButton1_Click(object sender, EventArgs e) { FormToolbox.GetInstance().Show(); } } }
多线程时的单例
防止多线程程序中,多线程同时访问FormToolbox类,调用GetInstance()方法,会造成创建多个实例的情况。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace ConsoleApp2 { public partial class FormToolbox : Form { private static FormToolbox ftb = null; //程序运行时创建一个静态只读的进程辅助对象 private static readonly object syncRoot = new object(); private FormToolbox() { InitializeComponent(); } public static FormToolbox GetInstance() { lock (syncRoot)//加锁 { if (ftb == null || ftb.IsDisposed) { ftb = new FormToolbox(); ftb.MdiParent = Form1.ActiveForm; } } return ftb; } private void FormToolbox_Load(object sender, EventArgs e) { } } }
双重锁定
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace ConsoleApp2 { public partial class FormToolbox : Form { private static FormToolbox ftb = null; //程序运行时创建一个静态只读的进程辅助对象 private static readonly object syncRoot = new object(); private FormToolbox() { InitializeComponent(); } public static FormToolbox GetInstance() { if(ftb == null) { lock (syncRoot)//加锁 { if (ftb == null || ftb.IsDisposed) { ftb = new FormToolbox(); ftb.MdiParent = Form1.ActiveForm; } } } return ftb; } } }
现在这样,我们不用让线程每次都加锁,而只是在实例未被创建的时候再加锁处理。同时也能保证多线程的安全。这种做法被称为双重锁定。
静态初始化或饿汉式单例类
即在自己被加载时就将自己实例化。解决了多线程环境下它是不安全的问题。
谈不上更好,只不过实现更简单:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApp2 { //阻止发生派生,而派生可能会增加实例 public sealed class Singleton { //在自己被加载的时候就将自己实例化 private static readonly Singleton instance = new Singleton(); private Singleton() { } public static Singleton GetSingleton() { return instance; } } }
这篇关于有些类也需要计划生育——单例模式的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2022-03-01沐雪多租宝商城源码从.NetCore3.1升级到.Net6的步骤
- 2024-05-08首个适配Visual Studio平台的国产智能编程助手CodeGeeX正式上线!C#程序员必备效率神器!
- 2024-03-30C#设计模式之十六迭代器模式(Iterator Pattern)【行为型】
- 2024-03-29c# datetime tryparse
- 2024-02-21list find index c#
- 2024-01-24convert toint32 c#
- 2024-01-24Advanced .Net Debugging 1:你必须知道的调试工具
- 2024-01-24.NET集成IdGenerator生成分布式全局唯一ID
- 2024-01-23用CI/CD工具Vela部署Elasticsearch + C# 如何使用
- 2024-01-23.NET开源的简单、快速、强大的前后端分离后台权限管理系统