这次将描述如何不适用内核模式的方式来使线程等待。SpinWait,它是一个混合同步构造,被设计为使用用户模式等待一段时间,然后切换到内核模式以节省CPU时间。

代码Demo:

using System;
using System.Threading;

在Main方法下面加入以下代码片段:

static volatile bool _isCompleted = false;

static void UserModeWait()
{
while (!_isCompleted)
{
Console.Write(".");
}
Console.WriteLine();
Console.WriteLine("Waiting is complete");
}
static void HybridSpinWait()
{
var w = new SpinWait();
while (!_isCompleted)
{
w.SpinOnce();
Console.WriteLine(w.NextSpinWillYield);
}
Console.WriteLine("Waiting is complete");
}

在Main方法中加入以下代码片段

var t1 = new Thread(UserModeWait);
var t2 = new Thread(HybridSpinWait);

Console.WriteLine("Running user mode waiting");
t1.Start();
Thread.Sleep(20);
_isCompleted = true;
Thread.Sleep(TimeSpan.FromSeconds(1));
_isCompleted = false;
Console.WriteLine("Running hybrid SpinWait construct waiting");
t2.Start();
Thread.Sleep(5);
_isCompleted = true;

工作原理:

当主程序启动时,定义了一个线程,将执行一个无止境的循环,知道20毫秒后主线程设置 _isCompleted变量为true。我们可以试验运行该周期为20~30秒,通过Windows任务管理器测量CPU的负载情况。取决于CPU内核数量,任务管理器将显示一个显著的处理时间。

我们使用volatile关键字来声明_isCompleted静态字段。Volatile关键字指出一个字段可能会被同事执行的多个线程修改。声明为volatile的字段不会被编译器和处理器优化为只能被单个线程访问。这确保了该字段总是最新的值。

然后我们使用了SpinWait版本,用于在每个迭代打印一个特殊标志位来显示线程是否切换为阻塞状态。运行该线程5毫秒来查看结果。刚开始,SpinWait尝试使用用户模式,在9个迭代后,开始切换线程为阻塞状态。如果尝试测量该版本的CPU负载,在Window任务管理器将不会看到任何CPU的使用。

线程同步-SpinWait的更多相关文章

  1. C#多线程之线程同步篇3

    在上一篇C#多线程之线程同步篇2中,我们主要学习了AutoResetEvent构造.ManualResetEventSlim构造和CountdownEvent构造,在这一篇中,我们将学习Barrier ...

  2. C#多线程之线程同步篇1

    在多线程(线程同步)中,我们将学习多线程中操作共享资源的技术,学习到的知识点如下所示: 执行基本的原子操作 使用Mutex构造 使用SemaphoreSlim构造 使用AutoResetEvent构造 ...

  3. 【C#进阶系列】28 基元线程同步构造

    多个线程同时访问共享数据时,线程同步能防止数据损坏.之所以要强调同时,是因为线程同步问题实际上就是计时问题. 不需要线程同步是最理想的情况,因为线程同步一般很繁琐,涉及到线程同步锁的获取和释放,容易遗 ...

  4. C#中的线程(二) 线程同步基础

    1.同步要领 下面的表格列展了.NET对协调或同步线程动作的可用的工具:                       简易阻止方法 构成 目的 Sleep 阻止给定的时间周期 Join 等待另一个线程 ...

  5. C#并行编程-线程同步原语

    菜鸟学习并行编程,参考<C#并行编程高级教程.PDF>,如有错误,欢迎指正. 目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 ...

  6. C#编程总结(三)线程同步

    C#编程总结(三)线程同步 在应用程序中使用多个线程的一个好处是每个线程都可以异步执行.对于 Windows 应用程序,耗时的任务可以在后台执行,而使应用程序窗口和控件保持响应.对于服务器应用程序,多 ...

  7. [转]C#编程总结(三)线程同步

    本文转自:http://www.cnblogs.com/yank/p/3227324.html 在应用程序中使用多个线程的一个好处是每个线程都可以异步执行.对于 Windows 应用程序,耗时的任务可 ...

  8. .net线程同步

    大家都晓得.NET中线程同步有以下几种方式: 临界区(Critical Section).互斥量(Mutex).信号量(Semaphore).事件(Event) 1.临界区:通过对多线程的串行化来访问 ...

  9. C#当中的多线程_线程同步

    第2章 线程同步 原来以为线程同步就是lock,monitor等呢,看了第二章真是大开眼界啊! 第一章中我们遇到了一个叫做竞争条件的问题.引起的原因是没有进行正确的线程同步.当一个线程在执行操作时候, ...

随机推荐

  1. 如何对正在运行的进程,进行heap profile

    简单来说, 就是先preload上tcmalloc, 日常用用没啥问题, 当感觉出现问题时, gdb attach 上, 然后执行 call HeapProfilerStart("xxx&q ...

  2. BFC 形成条件

    块格式化上下文(Block Formatting Context,BFC) 是Web页面的可视化CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域. 下列方式会创建块格 ...

  3. springcloud如何实现服务的平滑发布

    在之前的文章中我们提到服务的优雅下线,见: SpringCloud服务如何在Eureka安全优雅的下线 但这个对于ribbon调用其实是不平滑的,shutdown请求到后服务就马上关闭了,服务消费此时 ...

  4. 阿里云 CentOS7 安装 Nginx 后,无法访问的问题

    在阿里云实例中,选择 网络与安全中的安全组.修改安全组规则. 例如:   但是还是不行 需要这样排查 netstat -anp | grep 80 iptables -L -n   firewall- ...

  5. Redis】Java中使用Jedis操作Redis(Maven导入包)、创建Redis连接池

    如果我们使用Java操作Redis, 需要确保已经安装了 redis 服务及 Java redis 驱动. Maven项目可以直接在pom.xml中加入jedis包驱动: <!-- https: ...

  6. hive set 常用参数汇总

    1. set hive.auto.convert.join = true; mapJoin的主要意思就是,当链接的两个表是一个比较小的表和一个特别大的表的时候,我们把比较小的table直接放到内存中去 ...

  7. Js 动态添加的数据,监听事件监听不到

    在开发中遇到这种问题,就是有些数据,比如按钮是动态添加进去的,结果添加事件监听无效,直接写死在页面上是可以的. 这就是很明显的加载先后顺序的问题了. 解决的方法: $(document).ready( ...

  8. sping加载bean都发生了些什么

    问题描述:使用@Autowired注入的类,没有实例化 //Controller @RequestMapping(value="/deepblue") @Controller pu ...

  9. 解决MAMP启动mysql服务 但是Navicat连接不上

    问题重现 错误信息 2003 - Can't connect to MySQL server on '127.0.0.1' (61 "Connection refused") 解决 ...

  10. Wifi OKC 验证

    OKC(Opportunistic Key Caching) OKC,也叫OPC(Opportunistic PMK Caching),是微软定义的一套标准,并不在802.11标准中.不过多数厂商都支 ...