1. JVM线程同步机制
1 | int i=0; |
执行步骤:
- JVM首先在main memory(JVM堆),分配给i一个内存存储场所(常量池),并赋值为0
- 线程启动后,自动分配一片working memory区(通常是操作数栈),当线程执行到return i++时,JVM中并不是简单的一个步骤完成的。
i++的动作,在JVM中分为:装载i、读取i、进行i+1操作、存储i及写入i,五个步骤:
装载i
- 线程发起一个装载i的请求给JVM线程执行引擎,引擎接收请求后,会向main memory发起一个read i指令
- 当read i执行完毕后一段时间,线程会将i的值从main memory区复制到working memory区中
读取i
- 此步负责从main memory中读取 i
进行i + 1
- 线程执行
存储i
- 将i+1的值,赋给i,然后存储到working memory中
写入i
- 一段时间后,会将i的值写入main memory
上述步骤,由于不是原子性操作的问题,在多线程执行时,会出现问题
JVM把对于working memory的操作分为:
use
- 将变量值从work memory复制到线程执行引擎中
assign
- 将变量值复制到线程的work memory中
load
- 将main memory中read到的值,复制到work memory
store
- 将变量的值从work memory复制到main memory中,并等待main memory通过write动作写入此值
lock
- 同步操作main memory,给对象加锁
unlock
- 同步操作main memory,释放对象锁
- 同步操作main memory,释放对象锁
以上操作由线程执行
JVM对于main memory的操作分为:
read
- 从main memory中读取变量的值
write
- 将work memory的值写入main memory中
lock
unlock
以上操作由线程执行引擎执行
JVM保证一下操作是顺序执行的:
- 同一个线程上的操作一定是顺序执行的
- 对于main memory上的同一个变量的操作一定是顺序执行的,也就是不可能两个请求同时读取变量值
- 对于加锁的main memory上的对象操作,一定是顺序执行的,也就是两个以上加了lock锁的操作,同时肯定只有一个是在执行的
采用synchronized改造上边代码
1 | public synchronized int getNextId() { |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 我的生活小站!