首先来张图,一张 cpu的简图,仅从个人理解角度理解画的

  大体 解释下这张图 这是 一张 i5的简图i5 大家都知道 是双核四线程,(超线程技术)l1,l2,l3是 1,2,3级缓存。

  Cpu工作:每次计算任务 cpu 都去找l1,如果l1没有就去找l2,依次查找,然后依次将数据从内存加载l3,l2,l1 然后加载到 寄存器操作。

  现在引入 一个问题 a+=1; 怎么执行的

  首先 a+=1 是 分成 以下几部执行的

  1. 内存中找到a
  2. 在寄存器中 a+1
  3. 把结果写回内存中

  对应的 汇编代码 不写了→_→(我忘了)

  

  问题: 如果 a=0,2个线程 同时执行这端代码,结果是1还是 2呢?

看图 那么如果 核心1 和 核心2 同时 执行这段 代码(也就是 2个线程 同时执行)会发生什么………

假设1:当线程1 执行到 读取a 时,线程2 也读取a的值,当线程1执行+1时,线程2也同操作,最后结果显而易见 是1 (当然 cpu 不会让这件事件发生。因为 他有Cache Coherence处理)

假设2:当线程1执行完后,线程2在执行 结果就是2了。。

再举一个例子:

经典的 单例模式:(双检索)

 If(xxx==null)

 {

          Lock(“我是打酱油的”)

    {

            If(xxx==null)

      {

              xxx=new xxxxx();

       }

     }

 }

  大家都知道这个是线程安全的,但是 这种只是减少不安全的几率

  分析一下:

  这段代码执行的过程

  1、  创建对象

  2、  将对象的地址赋值给xxx

在即时编译器 是乱序执行的,调用分配内存和调用构造函数不是一个原子操作,可能导致先执行2,在执行1,那么就报错了

此例子来源 CLR via C#这本书,如果想详细了解请看这本书。

当然这个话题是想引起 对 ”原子性” 讨论 。

其实,每次我看到 原子性 都想到 线程锁,线程串行化等

当然这种 线程安全问题 利用锁(lock关键字) 是一种很好的 解决方案,有没有 更有效地解决方法呢?

答案是 System.Threading.Interlocked这个类

相关的信息:http://www.cnblogs.com/mgen/archive/2013/05/27/3101755.html#_h2

当然这个类的底层是 实现的呢 ,是这对方法: Thread.VolatileRead 和Thread.VolatileWrite

原理:是要求cpu 每次计算完后 都直接 写入内存 ,也就不存在文章开头存在问题。

最后 感谢 宝生兄的讲解 http://www.cnblogs.com/francisYoung/

最后推荐 一个大神的 博客 http://www.parallellabs.com

关于.net中线程原子性的自我总结的更多相关文章

  1. Java并发包中线程池ThreadPoolExecutor原理探究

    一.线程池简介 线程池的使用主要是解决两个问题:①当执行大量异步任务的时候线程池能够提供更好的性能,在不使用线程池时候,每当需要执行异步任务的时候直接new一个线程来运行的话,线程的创建和销毁都是需要 ...

  2. java并发学习--第四章 JDK提供的线程原子性操作工具类

    在了解JDK提供的线程原子性操作工具类之前,我们应该先知道什么是原子性:在多线程并发的条件下,对于变量的操作是线程安全的,不会受到其他线程的干扰.接下来我们就学习JDK中线程的原子性操作. 一.CAS ...

  3. synchronized使用及java中的原子性问题

    1.Synchronized关键字使用 class X { // 修饰非静态方法 synchronized void foo() { // 临界区 } // 修饰静态方法 synchronized s ...

  4. Cocos2dx中线程优先级

    Cocos2dx中线程优先级问题 不论是ios还是android,遇到耗时的任务都要另起线程处理,否则程序不能及时用户的反馈.游戏中如果一圈循环不能在1/frameRate(帧率是30则1/30)秒内 ...

  5. java中线程分两种,守护线程和用户线程。

    java中线程分为两种类型:用户线程和守护线程. 通过Thread.setDaemon(false)设置为用户线程: 通过Thread.setDaemon(true)设置为守护线程. 如果不设置次属性 ...

  6. Java中线程池的学习

    线程池的基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理.当有线程任务时,从池中取一个,执行完成后线程对象归池,这样可以避免反复创建线程 ...

  7. boost中asio网络库多线程并发处理实现,以及asio在多线程模型中线程的调度情况和线程安全。

    1.实现多线程方法: 其实就是多个线程同时调用io_service::run for (int i = 0; i != m_nThreads; ++i)        {            boo ...

  8. java中线程机制

    java中线程机制,一开始我们都用的单线程.现在接触到多线程了. 多线性首先要解决的问题是:创建线程,怎么创建线程的问题: 1.线程的创建: 四种常用的实现方法 1.继承Thread. Thread是 ...

  9. worker进程中线程的分类及用途

    worker进程中线程的分类及用途 欢迎转载,转载请注明出版,徽沪一郎. 本文重点分析storm的worker进程在正常启动之后有哪些类型的线程,针对每种类型的线程,剖析其用途及消息的接收与发送流程. ...

随机推荐

  1. javaScript的函数(Function)对象的声明(@包括函数声明和函数表达式)

    写作缘由: 平时再用js写函数的时候,一般都是以惯例 function fn () {} 的方式来声明一个函数,在阅读一些优秀插件的时候又不免见到 var fn = function () {} 这种 ...

  2. order by调优的一些测试

    表结构信息:mysql> show create table tb\G*************************** 1. row *************************** ...

  3. XtraGrid的若干种用法 z

    支持多种类型的数据集合作为数据源 XtraGrid与传统的DataGridView一样,支持多种类型作为其数据源.下面例子是将DataTable, List<T>和数组分别绑定到XtraG ...

  4. 获取手机内存\可用内存\单个APP运行内存

    /** 手机总内存 */ private String getTotalMemory() { // 系统内存信息文件 String str1 = "/proc/meminfo"; ...

  5. CentOS7 mariadb 修改编码

    CentOS7 mariadb 编码的修改: 网上看了不少的解决方案,要么是比较老的,要么是不正确,测试成功的方式,记录备查. 登录MySQL,使用SHOW VARIABLES LIKE 'chara ...

  6. Linux服务器下没有root权限装Matlab R2013a

    Matlab R2013a Unix版下载地址 注意:由于我是在单位的集群系统上装Matlab,没有root权限,故下载下来的.iso文件不能在linux下用mount命令挂载,故先在Win下解压,再 ...

  7. java集合框架1

    1.综述 所有集合类都位于java.util包下.集合中只能保存对象(保存对象的引用变量).(数组既可以保存基本类型的数据也可以保存对象). 当我们把一个对象放入集合中后,系统会把所有集合元素都当成O ...

  8. Fast Intro To Java Programming (1)

    基本语法 编写Java程序时,应注意以下几点: 大小写敏感:Java是大小写敏感的,这就意味着标识符Hello与hello是不同的. 类名:对于所有的类来说,类名的首字母应该大写.如果类名由若干单词组 ...

  9. mysql performance_schema 初探

    mysql  performance_schema 初探: mysql 5.5 版本 新增了一个性能优化的引擎: PERFORMANCE_SCHEMA 这个功能默认是关闭的: 需要设置参数: perf ...

  10. Linux cat命令参数及使用方法详解

    cat是Linux系统下用来查看文件连续内容用的指令,字面上的含意是“concatenate”(连续)的缩写.除了用来作为显示文件内容外,cat指令也可用于标准流上的处理,如将显示的信息转入或附加另一 ...