java并发编程(五)
java多线程编程(五)
java内存模型分类
使用写缓冲区临时保存向内存中写入数据。
Why?
提升效率:
1)写缓冲区可以保证指令流水线持续运行,它可以避免因为解决器停顿下来等待向内存写入数据而产生的推迟
2)通过以批解决的方式刷新写缓冲区,以及合并写缓冲区中对同一内存地址的屡次写,减少对内存总线的占用。
缺点:
每个解决器上的写缓冲区,仅仅对它所在的解决器可见。这个特性会对内存操作的执行顺序产生重要的影响:解决器对内存的读/写操作的执行顺序,不肯定与内存实际发生的读/写操作顺序一致
eg:
解决器/示例项 | ProcessorA | ProcessorB |
---|---|---|
代码 | a=1; //A1</br>x=b;//A2 | b=2;//B1</br>y=a;//B2 |
运行结果 | 初始状态:a=b=0;</br>解决允许执行后得到的结果:x=y=0 |
具体起因如下:
解决器A和解决器B可以同时把共享变量写入到自己的写缓存区(A1,B1),而后从内存中
读取另一个共享变量(A2、B2),最后才把自己写缓存区中保存的脏数据刷新到内存中(A3、B3)当以这种时序执行时,程序即可以得到x=y=0的结果。
从内存操作实际发生的顺序来看,直四处理器A执行A3来刷新自己的写缓存区,写操作
A1才算真正执行了。尽管解决器A执行内存操作的顺序为:A1→A2,但内存操作实际发生的顺
序却是A2→A1。此时,解决器A的内存操作顺序被重排序了(解决器B的情况和解决器A一样,
这里就不赘述了)。
这里的关键是,因为写缓冲区仅对自己的解决器可见,它会导致解决器执行内存操作的
顺序可能会与内存实际的操作执行顺序不一致。因为现代的解决器都会使用写缓冲区,因而现代的解决器都会允许对写-读操作进行重排序
happens-before简介
在JMM中,假如一
个操作执行的结果需要对另一个操作可见,那么这两个操作之间必需要存在happens-before关
系。这里提到的两个操作既可以是在一个线程之内,也可以是在不同线程之间。
与程序员密切相关的happens-before规则如下:
程序顺序规则:一个线程中的每个操作,happens-before于该线程中的任意后续操作。
监视器锁规则:对一个锁的解锁,happens-before于随后对这个锁的加锁。
volatile变量规则:对一个volatile域的写,happens-before于任意后续对这个volatile域的
读。传递性:假如A happens-before B,且B happens-before C,那么A happens-before C。
happens-before与JMM关系如下:
happens-before与JMM.png
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » java并发编程(五)