volatile

class Test
    {
        //volatile多用于多线程的环境,当一个变量定义为volatile时,读取这个变量的值时候每次都是从momery里面读取而不是从cache读。
        //这样做是为了保证读取该变量的信息都是最新的,而无论其他线程如何更新这个变量。


        //volatile 修饰符通常用于由多个线程访问但不使用 lock 语句对访问进行序列化的字段。
        //volatile 关键字可应用于以下类型的字段:
        //引用类型。
        //指针类型(在不安全的上下文中)。 请注意,虽然指针本身可以是可变的,但是它指向的对象不能是可变的。 换句话说,您无法声明“指向可变对象的指针”。
        //类型,如 sbyte、byte、short、ushort、int、uint、char、float 和 bool。
        //具有以下基类型之一的枚举类型:byte、sbyte、short、ushort、int 或 uint。
        //已知为引用类型的泛型类型参数。
        //IntPtr 和 UIntPtr。
        //可变关键字仅可应用于类或结构字段。 不能将局部变量声明为 volatile。

        static volatile bool _isCompleted = false;

        static void UserModeWait()
        {
            while (!_isCompleted)
            {
                Console.Write("②.");
            }
            Console.WriteLine();
            Console.WriteLine("③等待完成");
        }

        static void HybridSpinWait()
        {
            //自旋等待
            //一个轻量同步类型(结构体),提供对基于自旋的等待的支持。SpinWait只有在多核处理器下才具有使用意义。在单处理器下,自旋转会占据CPU时间,却做不了任何事。
            //SpinWait并没有设计为让多个任务或线程并发使用。因此,如果多个任务或者线程通过SpinWait的方法进行自旋,那么每一个任务或线程都应该使用自己的SpinWait实例。
            var w = new SpinWait();
            while (!_isCompleted)
            {
                // 执行单一自旋。
                w.SpinOnce();
                // 判断对SpinWait.SpinOnce() 的下一次调用是否触发上下文切换和内核转换。
                //由NextSpinWillYield属性代码可知,若SpinWait运行在单核计算机上,它总是进行上下文切换(让出处理器)。
                //SpinWait不仅仅是一个空循环。它经过了精心实现,可以针对一般情况提供正确的旋转行为以避免内核事件所需的高开销的上下文切换和内核转换;
                //在旋转时间足够长的情况下自行启动上下文切换,SpinWait甚至还会在多核计算机上产生线程的时间片(Thread.Yield())以防止等待线程阻塞高优先级的线程或垃圾回收器线程。
                Console.WriteLine("是否触发上下文切换和内核转换: "+w.NextSpinWillYield);
            }
            Console.WriteLine("③等待完成");
        }

        public static void RunTest()
        {
            var t1 = new Thread(UserModeWait);
            var t2 = new Thread(HybridSpinWait);

            Console.WriteLine("①运行用户模式等待");
            t1.Start();

            //将当前执行RunTest()方法线程挂起指定的时间。 让t1线程执行输出②.
            Thread.Sleep(1);
            _isCompleted = true;

            //将当前线程阻塞指定的时间
            Thread.Sleep(TimeSpan.FromSeconds(1));
            _isCompleted = false;


            Console.WriteLine("①运行混合SpinWait构造 等待");
            t2.Start();
            Thread.Sleep(5);
            _isCompleted = true;

            Console.ReadKey();
        }
    }
  •  

运行结果如图:

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值