0
点赞
收藏
分享

微信扫一扫

java并发原理实战(6) -- volatile的原理理解


文章目录

  • ​​volatile原理理解​​
  • ​​引子​​
  • ​​volatile的原理:​​
  • ​​lock指令​​
  • ​​什么时候使用volatile​​

volatile原理理解

引子

看一段代码:

public class Demo {
private int a= 1;

public int getA() {
return a;
}

public void setA(int a) {
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.a = a;
}

public static void main(String[] args) {
Demo demo = new Demo();
new Thread(
() -> {
demo.setA(10);
}
).start();
new Thread(
() -> {
System.out.println(demo.getA());
}
).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("最终的值为=="+ demo.a);
}
}

运行结果:

java并发原理实战(6) -- volatile的原理理解_高速缓存

发现,结果并不相同。

解决方式1:

java并发原理实战(6) -- volatile的原理理解_高速缓存_02


运行结果:

java并发原理实战(6) -- volatile的原理理解_主存_03

除此以外,还有一种方式,用volatile:

java并发原理实战(6) -- volatile的原理理解_缓存_04

public class Demo {
private volatile int a = 1;

public int getA() {
return a;
}

public void setA(int a) {
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.a = a;
}

public static void main(String[] args) {
Demo demo = new Demo();
new Thread(
() -> {
demo.a = 10;
}
).start();
new Thread(
() -> {
System.out.println(demo.a);
}
).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("最终的值为==" + demo.a);
}
}

运行结果:

java并发原理实战(6) -- volatile的原理理解_并发编程_05

volatile的原理:

推荐文章

深入理解Volatile关键字及其实现原理

java并发原理实战(6) -- volatile的原理理解_缓存_06

工作内存Work Memory其实就是对CPU寄存器和高速缓存的抽象,或者说每个线程的工作内存也可以简单理解为CPU寄存器和高速缓存。

那么当写两条线程Thread-A与Threab-B同时操作主存中的一个volatile变量i时,Thread-A写了变量i,那么:

  • Thread-A发出LOCK#指令
  • 发出的LOCK#指令锁总线(或锁缓存行),同时让Thread-B高速缓存中的缓存行内容失效
  • Thread-A向主存回写最新修改的i

Thread-B读取变量i,那么:

  • Thread-B发现对应地址的缓存行被锁了,等待锁的释放,缓存一致性协议会保证它读取到最新的值

由此可以看出,volatile关键字的读和普通变量的读取相比基本没差别,差别主要还是在变量的写操作上。

java并发原理实战(6) -- volatile的原理理解_高速缓存_07

lock指令

java并发原理实战(6) -- volatile的原理理解_主存_08

什么时候使用volatile

java并发原理实战(6) -- volatile的原理理解_高速缓存_09


举报

相关推荐

0 条评论