C# 之 volatile关键字解析

一,概念解释

volatile 关键字指示一个字段可以由多个同时执行的线程修改。

出于性能原因,编译器,运行时系统甚至硬件都可能重新排列对存储器位置的读取和写入。 声明了 volatile 的字段不进行这些优化。

添加 volatile 修饰符可确保所有线程观察易失性写入操作(由任何其他线程执行)时的观察顺序与写入操作的执行顺序一致。 不确保从所有执行线程整体来看时所有易失性写入操作均按执行顺序排序。


二,修饰类型

volatile 关键字可修饰于以下类型的字段:

  • 引用类型。
  • 简单类型,如sbyte、byte、short、ushort、int、uint、char、float 和 bool。
  • 具有以下基本类型之一的 enum 类型:byte、sbyte、short、ushort、int 或 uint。
  • 已知为引用类型的泛型类型参数。
  • IntPtr 和 UIntPtr。

其他类型(包括 double 和 long)无法标记为 volatile,因为对这些类型的字段的读取和写入不能保证是原子的。 若要保护对这些类型字段的多线程访问,可使用 Interlocked 类成员或使用 lock 语句保护访问权限。

volatile 关键字只能应用于 class 或 struct 的字段。 并且不能将局部变量声明为 volatile。


三,实际运用

通常情况下我们是这样使用单例模式的,代码如下:

/// <summary>
/// 单例
/// </summary>
class Singleton
{
    private static Singleton _ins;

     public static Singleton Instance
     {
        get
        {
            if (_ins == null)
            {
                _ins = new Singleton();
            }
            return _ins;
        }
    }

    // 私有化构造
    private Singleton() { }

}

   

若我们程序需要在多线程中执行时,上面这种写法就可能会有问题,一种极限情况就是,两个线程同时进入if (_ins == null)时,此时会new 两个对象出来,这显然违背了我们使用单例模式的意愿,进而优化出来下面这种单例写法,在多线程中使用

 /// <summary>
 /// 多线程单例
 /// </summary>
 class SingletonThread
 {
    private static volatile SingletonThread _ins;

    private static object lockHelper = new Object { };

    public static SingletonThread Instance
    {
        get
        {
            if(_ins == null)
            {
                lock (lockHelper)
                {
                   if(_ins == null)
                    	_ins = new SingletonThread();
                }
            }
            return _ins;
        }
    }

    // 私有化构造
    private SingletonThread() { }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

陈言必行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值