JMM概念

本文探讨如何优化串行化程序性能,通过Amdahl定律和Gustafson定律理解并行化的重要性。同时,深入解析Java内存模型(JMM)在多线程并发中的原子性、可见性和有序性挑战,以及指令重排对程序执行顺序的影响。理解这些概念对于优化并发程序和确保数据一致性至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题:如何提高串行化程序的性能?

首先我们先了解并行的两个定律:

Amdahl定律:表明,我们需要从根本上解决问题,优化在与串行化比重,提高系统并行化模块比重,这样加入合理的cpu个数,才能以最小的投入,得到最大的优化。强调:一味的提高cpu个数对性能并没有改变!

Gustafson定律:并行化比重占的越多,那个增加cpu个数就能实现线性增长。

即两个定律并不矛盾:当串行比列为F=1时,加速比都为1, 当串行化比列为100%时,加速比为n(处理器个数)

回到JMM: 强调,程序往往会出现并发,那么在并发中,如何保证并行部分的程序数据是安全性和一致性。

JMM的关键技术点在多线程的原子性,可见性,有序性。

原子性:指一个操作不可被中断,即使在多线程下,也是不可被干扰,好比32位系统中的long,它的读写并不是原子性的,所有在多线程下,数据很可能会被写乱!

可见性:在并发情况下,系统不能保证并行程序能够察觉到全局变量值的改变,(由于缓存优化或者硬件优化,指令重排等)

有序性:往往一个程序,会根据系统的指令重排的优化导致乱序, 指令重排可以保证串行语义一致,但是并不能保证多线程的语义是否一致

指令重排:c=a+b

在汇编语言中:每一条指令并不能一步走完,需要执行取值IF,译码和取寄存器操作数ID,执行或者有效计算EX,存储器MEM, 写回WB。 所有发明了流水线,但是有一个问题就是,1. a取值 2.b取值,a译码 3.a准备计算,b译码 ====》这个时候a准备计算了,但是b还在译码, 所以导致需要等待一个时间,这样将导致后续所有指令都会等待一个时间。所有有了指令重排,比如现在又有e = f + g 这个时候程序不会等待,而是先取值f这样,就不会导致程序停留啥也不干!

指令重排必须遵循happen-before原则:

1. 程序顺序原则

2. volatile规则:v变量的写先发与读,保证可见性

3. 锁规则:解锁必须发生在加锁后

4.传递性:A->B->C 那么A一定先于C

5.线程的所有操作必须先于线程的终结(Thread.join())

6. 线程的中断先于被中断线程的代码

7.对象的构造函数执行结束先于finalize()

8.线程的start()方法优先与它每一个动作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值