为了解决线程并发问题语言内部引用了同步块,volatile关键字机制

一、同步块

  详情见我的其它博客

二、volatile

  volatile修饰的变量(成员变量)等保证操作的有序性、可见性,但不能保证原子性

  JVM有一块内存为栈内存为线程私有,每一个线程运行时都会分配一个栈内存来保存运行时变量信息,当某个线程访问对象值的时候,通过对象引用找到对应在堆内存(线程共享,存放对象和数组)的值,把值load到栈内存建立一个副本,之后改变变量值就跟堆内存的值没有关系了,而是直接改变的本地内存的值,在修过完之后在某一刻(线程退出之前)自动把本地内存的值回写到主内存(堆内存),其它线程进来同上反复

 

  1、read-load 线程启动时从主内存读取数据到本地内存(栈内存)

  2、use-assign 代码更新本地内存变量值,可执行多次

  3、store-write 将工作内存的数据更新到主内存(堆内存)线程退出之前可执行多次

  但这个过程中并不能保证原子性,当load到本地内存后,主内存中的值发生变化,本地内存值是不知道的然后本地内存值发生变化回写到主内存时数据就会被覆盖一致不准

  也就是说JVM只能保证将变量从主内存加载到本地内存是最新的

  volatile修饰的变量如果都是原子操作那么是安全的,如果不是原子操作(比如运算结果需要依靠自身值如:i++)那么也会出现并发问题