英文好的,可跳过,直接打开底部的“参考“链接。

代码变序--reordering of memory operations

大概4年前,阅读了这篇文章后http://www.albahari.com/threading/,我就自我满足,多线程编程不过就是用那些工具而已。

今天,读了一篇文章后,http://msdn.microsoft.com/en-us/magazine/jj863136.aspx,才发现C#代码是可以变序的(上面的文章也提到了,忘得一干二净)。

举例,你写出如下的代码

  1. void Init() {
  2. _data = 42;
  3. _initialized = true;
  4. }

JIL运行时的代码却可以像这样(不是IL代码哦,IL编译出代码与源代码是一致的)

  1. void Init() {
  2. _initialized = true;
  3. _data = 42;
  4. }

这个坑爹的JIL优化,如果不注意,可能就不会抓住bug所在。底部有我写的再现方法。先别运行程序,试试猜猜结果有几种可能。

总结:浮躁+记忆力差是很致命的,必须要找适合自己的工作方式。深入理论上理解+上手验证,这样才算消化,也不容易忘。

不重复造轮子,更不能重复学习。

参考:

http://msdn.microsoft.com/en-us/magazine/jj863136.aspx

http://msdn.microsoft.com/en-us/magazine/jj883956.aspx

    class Program
{
static void Main(string[] args)
{
DataInit di = new DataInit();
new Thread(() => { di.Init(); }) { IsBackground = true }.Start();
new Thread(() => { di.Print(); }) { IsBackground = true }.Start(); Console.WriteLine("Running... Press enter to quit");
Console.ReadLine();
}
} public class DataInit
{
private int _data = ;
private bool _initialized = false;
//准备些无用的field
private char _c = '';
private int _data1 = ;
private int _data2 = ;
private int _data3 = ;
private int _data4 = ; public void Init()
{
_data = ; // Write 1
_initialized = true; // Write 2
//下面的field赋值是用来触发JIL 优化的,如何触发的原理,我不知道:(。
///*try屏蔽下面的代码,结果很可能就是42了
_c = '';
_data1 = ;
_data = ;
_data2 = ;
_data3 = ;
_data4 = ;
}
public void Print()
{
Console.WriteLine(_data);
Console.WriteLine(_initialized); if (_initialized)
{
Console.WriteLine(_data); //should 42,有时候确是0
}
else
{
Console.WriteLine("Not initialized");
}
}
}

C# 多线程的坑 之 代码变序的更多相关文章

  1. 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例

    前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...

  2. [LeetCode系列] 变序词查找问题(Anagrams)

    给定一系列词, 找出其中所有的变序词组合. Note: 变序词 - 组成字符完全相同但次序不同的单词. 如dog和god, ate和eat. 算法描述: 使用map<string, vector ...

  3. STL学习笔记(变序性算法)

    变序性算法改变元素的次序,但不改变元素值. 这些算法不能用于关联式容器,因为在关联式容器中,元素有一定的次序,不能随意变动. 逆转元素次序 void reverse(BidirectionalIter ...

  4. 用AOP来让你的JS代码变得更有可维护性吧

    此文已由作者吴佳祥授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 好吧我承认这是篇任务. 最近看到个消息,ES2017已经定稿了,心想,我去,还完全没了解ES2016呢,ES ...

  5. 【如何让代码变“高级”(二)】-这样操作值得一波666(Java Stream)(这么有趣)

    [如何让代码变“高级”(二)]-这样操作值得一波666(Java Stream)(这么有趣) 开发中的代码 在开发中的代码是不是很常见这样的代码: 这样的? for循环取元素取值 List<Us ...

  6. java 多线程: Thread 并发访问-代码块同步synchronized {};String作为被锁的对象

    方法同步的弊端 方法同步的时候,如果一个方法需要线程安全控制的代码速度其实很快,但是还有其他的业务逻辑代码耗时非常长(比如网络请求),这样所有的线程就在这一块就等待着了,这样造成了极大的资源浪费如果并 ...

  7. 多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)

    前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...

  8. css 填坑常用代码分享

    以下是常用的代码收集,没有任何技术含量,只是填坑的积累.转载请注明出处,谢谢. 因为提交比较麻烦,后来转置github:https://github.com/jsfront/src/blob/mast ...

  9. 多线程爬坑之路-ThreadLocal源码及原理的深入分析

    ThreadLocal<T>类:以空间换时间提供一种多线程更快捷访问变量的方式.这种方式不存在竞争,所以也不存在并发的安全性问题. This class provides thread-l ...

随机推荐

  1. Hacker(15)----嗅探原理

    嗅探指窃听网络中流经的数据包,这里的网络一般指用集线器或路由器组建的局域网.通过嗅探并解析数据包,便可知道数据包中的信息,一旦含有账户密码等隐私信息就可能造成个人资金损失. 嗅探数据包无法通过输入命令 ...

  2. C#遍历获取枚举的值,名和属性

    获取: Type type = typeof(ParamServiceType); var values = Enum.GetValues(type); ; i < values.Length; ...

  3. Http请求和响应报文基础知识

    一 HTTP请求报文(http://en.wikipedia.org/wiki/List_of_HTTP_header_fields) 请求报文由三部分组成:请求行,请求头和请求体. 请求行:请求方法 ...

  4. ScrollView 的使用(非原创)

    1.ScrollView滚动视图是指当拥有很多内容,屏幕显示不完时,需要通过滚动跳转来显示的视图.ScrollView只支持垂直滚动 <ScrollView xmlns:android=&quo ...

  5. Content-Disposition的使用和注意事项(转载)

    Content-Disposition的使用和注意事项 最近不少Web技术圈内的朋友在讨论协议方面的事情,有的说web开发者应该熟悉web相 关的协议,有的则说不用很了解.个人认为这要分层次来看待这个 ...

  6. Linux串口编程のtermios 结构

    termios 结构是在POSIX规范中定义的标准接口,它类似于系统V中的termio接口,通过设置termios类型的数据结构中的值和使用一小 组函数调用,你就可以对终端接口进行控制. 可以被调整来 ...

  7. html简单样式

    1.外部样式表 link rel="stylesheet" type="text/css" href="bbb.css"> 2.内部样 ...

  8. automaticallyAdjustsScrollViewInsets的作用

    简单点说就是automaticallyAdjustsScrollViewInsets根据按所在界面的status bar,navigationbar,与tabbar的高度,自动调整scrollview ...

  9. poj 3158kickdown

    我是来吐槽poj的!!! 第一次做poj,被题目中的输入输出格式打败了 ,醉了醉了 Description A research laboratory of a world-leading autom ...

  10. Js中单引号和双引号的区别

    <html> <body> <input value="外双引号内双引号-错误" type="button" onclick=&q ...