Java多线程

主内存与工作内存

Java内存模型规定了所有的变量都存储在主内存中(物理上仅是虚拟机内存的一部分),每条线程还有自己的工作内存,线程的工作内存中保存了被该线程使用的变量的主内存副本,线程对变量的所有操作(读取,赋值等)都必须在工作内存中进行,而不能直接读写主内存中的数据,不同线程之间也无法直接访问对方工作内存中的变量,线程间变量值的传递需要通过主内存来完成。

这里的主内存,工作内存与之前讲的Java内存区域中的Java堆,栈,方法区等并不是同一个层次的对内存的划分,这两者基本上是没有任何关系的。

volatile

当一个变量被定义为volatile后,它具备两条特性:1.保证此变量对所有的线程的可见性。2.禁止指令重排

可见性是指当一个线程修改了这个变量的值,新值对于其他线程来说是可以立即得知的。而普通变量不能做到这一点,普通变量的值在线程间传递时需要通过主内存完成。需要注意的是仅仅可见性并不能保证并发安全,因为Java的普通运算符并不是原子操作。

禁止指令重拍指的是CPU在执行指令的时候会在不改变结果的情况下,进行指令重排。在同一个线程的方法执行过程中无法感知到这点。举个例子:

setA()
setB()
flag=true

假如有个线程执行上述操作我们本意是先设置A,B完成后flag赋值为true,但是在另一个线程看来CPU可能因为指令重排导致先把flag赋值为true再执行设置A,B。

volatile的原理就在于赋值后多了一个指令,这个指令的作用是内存屏障

锁升级

见Java并发部分。

posted @ 2021-09-13 22:43  刚刚好。  阅读(13)  评论(0编辑  收藏  举报