1.共享变量:如果一个变量在多个线程中的工作内存中都存在副本,那么这个变量就是这些变量的共享变量
2.可见性:一个线程对共享变量的修改能够及时的被其它线程看到
java内存模型
java内存模型描述了java程序中各种变量(线程共享变量)的访问规则,以及封装了在jvm中将变量存储到内存和从内存
中读取变量的底层细节
1:所有的共享变量都存储在主内存中
2.每个线程都有自己独立的工作线程,里面保存了改线程使用共享变量的副本
Java规定:线程对共享变量的所有操作都必须在自己的工作内存中进行,不能直接从主内存中读写;不同线程之间
无法直接访问其它线程工作内存中的共享变量,线程间共享变量值的传递需要通过主内存来完成
共享变量可见性的实现原理
线程对共享变量的修改想要被其它线程及时看到,必须经过如下两个步骤
1.将工作内存中更新过的共享变量刷新到主内存中
2.将主内存中最新的共享变量的值更新到工作内存中
事项共享变量的可见性必须保证两点:
1.线程修改后的共享变量能够及时的从工作内存更新到主内存中
2.其它线程能够及时的将共享变量的最新值从主内存中更新到自己的工作内存中
java语言层面支持可见性的实现方式
1.synchronized 原子性,可见性
2.volatile 可见性
jmm关于synchronized的实现原理:
1.线程解锁前必须把共享变量的最新值刷新到主内存
2.线程加锁时,将清空工作内存中的共享变量,从而使用共享变量时需要从主内存重新读取最新的值
加锁和解锁为同一把锁
synchronized执行过程
1.获取互斥锁
2.清空工作内存
3.从主内存中拷贝共享变量的最新值副本到工作内存
4.执行代码
5.将更改后的共享变量值刷新到主内存中
6.释放互斥锁
synchronized(this)表示锁当前对象,如果当前对象有多个synchronized方法,其它线程调用其它synchronized方法时也就被阻塞。
volatile可见性
volatile能够保证共享变量的可见性,不能保证共享变量复合操作的原子性
volatile如何实现共享变量的可见性:
1.对volatile变量执行写操作时,会在写操作后执行一条store屏障指令,它会把cpu的缓存强制刷新到主内存中,也能防止处理器
把volatile之前的变量重排序到vvolatile变量之后
2.对volatile变量执行读操作,会在读操作前加一条load屏障指令,它会强制使缓存区的缓存失效,让线程从主内存中读取数据,
也禁止重排序。
通俗的讲:volatile变量在每次被线程访问时,都强迫从主内存中读取该变量的值,而当该变量发生变量时,又会强迫线程将最新
的值刷新到主内存中,这样任何时刻,不同线程总能看到该变量的最新值
线程写volatile变量的过程
1.改变线程工作内存中volatile变量副本的值
2.将改变后的副本值从工作内存刷新到主内存
线程读volatile变量的过程
1.从主内存中读取volatile变量的最新值到线程的工作内存中
2.从工作内存中读取volatile变量的副本
number++
1.从内存中读取number的值
2.将number的值加1
3.将改变后的值写入内存