首先我们先看一下每个线程对应我们内存的模型。
每个线程都有一个私有的本地内存,存储共享变量的副本,从主内存获取到数据。
线程A和线程B通信的过程是线程A把本地内存的数据同步到主内存中,线程B在从主内存中获取到共享变量刷新到本地内存中。
主内存中有一个共享变量 x=0,线程A想把x=0>---->x=1,首先本地内存中修改x=1然后同步主内存,线程B从主内存中读取变量然后载刷新到线程B的本地内存中,线程A什么时候去刷新主内存的变量这个是不确定的,线程B什么时候去同步也是不确定,就导致了线程安全性问题.
volitile可以解决这种可见性问题
1、 对于声明volitile的变量,在每次进行写操作的,jmv会向处理器发送一条Lock前缀的指令,会把这个变量所在的缓存行数据 写回系统内存中。
2、在多处理器的情况下,保证每个处理器缓存一致性的特点,就会实现缓存一致性协议。
3、多处理器会监听到主内存中的变量是否发生变化,查看自己缓存的值是否过期了,设置失效,重新从主存中读取。
但是会出现复合性问题
Volatile int i = 0;
public void update(){
i++;
}
I++涉及到三个步骤,所以会有并发问题。
syschronized主要是实现一个锁的机制
使用monitor进行加锁,如果没有获取到锁的线程会放进一个queue里,进行再次获取锁。