笔记:并发编程的三大特性,可见性、有序性、原子性

跟着马老师的视频复习了下并发编程的三大特性(可见性、有序性、原子性)  ,温故而知新,马老师讲的不错!

可见性

两个线程分别同时去修改一份变量的拷贝时,会产生修改值不一样的问题,这样的问题就是可见性问题。 sychronized保证原子性的同时也会保证可见性,会做一个与主内存之间的同步操作

运算单元取寄存器的数据花1个单位时间,运算单元从主内存中取数据需要花100个单位的时间,相差100倍

volatile的底层实现就是一把锁,会把总线也一起锁起来,lock指令不能单独执行,需要加一个附加指令(但是不能直接加空指令),这里的addl 0相当于空指令

按一个缓存行(按块存取),工业最佳实践,一个缓存行大小是64个字节

不管加不加volatile和sychronized,只要缓存行存在,这个协议都会时不时的执行触发一下,intel的叫MESI,缓存行一致性协议,AMD的叫啥?

 

2.有序性

同一个线程中间程序里面的两条指令是有可能乱序执行的。

CPU执行两个指令,一个指令去主类存取数据,一个指令去寄存器做变量加1,去主内存取数据可能需要一个100的时间单位,但是去个寄存器做变量加1只需要一个单位的时间,这个时候在等主内存返回数据的时候又需要99个单位的时间,最好在等待99个单位时间过程中再执行其它的寄存器操作,这样可以提高效率

并不是所有的指令都会进行乱序执行,只有单线程最终能保持一致性的时候cpu才会进行指令乱序执行

 

3. 原子性

锁的本质是原子性,互斥锁sychronized

当初始化还没有完全完成时,就先启动了一个线程,这时读取到的是半初始化状态的成员变量m=0而不是m=8 java对象的创建过程会编译成5条汇编指令,

1.分配内存块(初始化的时候成员变量还没有赋值)

2.初始化调用构造方法,赋值成员变量

3.将对象与初始化后的内存块建立关联关系

DCL中的第一个判空删掉了的话,所有的线程过来都会加一把锁,会产生锁竞争的资源浪费

 

第一个线程if(t != null) new T()使用了半初始化状态的对象,第二个线程判空结果不为空直接使用了这个半初始化的对象,可能实际过程中不会出现这种情况,但是理论上是会出现的,所以即使DCL也需要考虑加上volatile

volatile的作用 保持可见性 禁止指令重排 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值