84669 person learning
152542 person learning
20005 person learning
5487 person learning
7821 person learning
359900 person learning
3350 person learning
180660 person learning
48569 person learning
18603 person learning
40936 person learning
1549 person learning
1183 person learning
32909 person learning
走同样的路,发现不同的人生
简单说你可以这么看
read
write
load
store
之所以会这么麻烦,是因为现代电脑都有不止一个CPU,每个CPU都有自己的1级2级甚至3级缓存,CPU之间共享主存,一个CPU对主存所做的改动并不会自动被其它CPU发现,必须有某种机制让其它CPU知道这一点,当然最简单的思路是让cache和主存永远同步,但cache的速度远高于主存,强制同步其实相当于把cache强制降速,这对于程序执行效率是不利的。现在的做法是选择性的同步,当你不需要同步时,只需要一次load,然后就可以多次read/write,避免和主存的同步,这样可以让这个CPU保持最高的效率运转;当你需要同步时,用store将变更写回主存,JVM/CPU/MMU会协调将这个变更通知到其它CPU以保证程序的正确性。use是用来配合上述过程的,只有use了特定变量的CPU才会收到针对这个变量做store时发出的通知,这样就避免了无谓的CPU cache flush操作。
use
lock/unlock是传统方式,用来限制CPU对共享区域操作的,如果一个变量被lock了,那么其它所有CPU针对这个变量做出的lock操作都回阻塞直到拥有者释放这个锁。
lock
unlock
以上是一个极为简化的memory model说明,里面还有很多细节需要长篇大论才说的清。
简单说你可以这么看
read
是把变量从shared memory读入CPU local memory,或者说从内存读入CPU cache,write
反之load
是把变量从CPU local memory读入JVM stack,你可以认为它是把数据从CPU cache读入到“JVM寄存器”,store
反之之所以会这么麻烦,是因为现代电脑都有不止一个CPU,每个CPU都有自己的1级2级甚至3级缓存,CPU之间共享主存,一个CPU对主存所做的改动并不会自动被其它CPU发现,必须有某种机制让其它CPU知道这一点,当然最简单的思路是让cache和主存永远同步,但cache的速度远高于主存,强制同步其实相当于把cache强制降速,这对于程序执行效率是不利的。
现在的做法是选择性的同步,当你不需要同步时,只需要一次load,然后就可以多次read/write,避免和主存的同步,这样可以让这个CPU保持最高的效率运转;当你需要同步时,用store将变更写回主存,JVM/CPU/MMU会协调将这个变更通知到其它CPU以保证程序的正确性。
use
是用来配合上述过程的,只有use
了特定变量的CPU才会收到针对这个变量做store
时发出的通知,这样就避免了无谓的CPU cache flush操作。lock
/unlock
是传统方式,用来限制CPU对共享区域操作的,如果一个变量被lock
了,那么其它所有CPU针对这个变量做出的lock
操作都回阻塞直到拥有者释放这个锁。以上是一个极为简化的memory model说明,里面还有很多细节需要长篇大论才说的清。