当前位置:   article > 正文

java多线程之volatile总结_线程间 volatile变量传入线程类

线程间 volatile变量传入线程类

java内存模型

所有的变量都存储在主内存(Main Memory)中。每个线程还有自己的工作内存(Working Memory),线程的工作内存中保存了该线程使用到的变量的主内存的副本拷贝,线程对变量的所有操作(读取、赋值等)都必须在工作内存中进行,而不能直接读写主内存中的变量。不同的线程之间也无法直接访问对方工作内存中的变量,线程之间值的传递都需要通过主内存来完成。

可见性:可见性指多个线程操作一个共享变量时,其中一个线程对变量进行修改后,其他线程可以立即看到修改的结果。

使用volatile修饰的变量在修改后可以被立即刷新到主内存中,其他线程可以立即看到修改后的值.当有其他线程需要读取时,它会去主内存中读取最新值。相反,普通的共享变量被修改之后,不能保证及时更新到主内存,导致某些线程读取时还是旧值,因此无法保证其可见性。

看代码:

  1. class VolatileDemo extends Thread{
  2. public boolean flag = true;
  3. public void setFlag(boolean flag){
  4. this.flag = flag;
  5. }
  6. @Override
  7. public void run() {
  8. System.out.println("子线程开始.....");
  9. while (flag){
  10. }
  11. System.out.println("子线程执行结束....");
  12. }
  13. }
  14. public class ThreadVolatileDemo {
  15. public static void main(String[] args) throws InterruptedException {
  16. VolatileDemo volatileDemo = new VolatileDemo();
  17. volatileDemo.start();
  18. Thread.sleep(1000);
  19. volatileDemo.setFlag(false);
  20. System.out.println("flag已经修改为false!");
  21. Thread.sleep(1000);
  22. System.out.println("flag==="+volatileDemo.flag);
  23. }
  24. }

运行结果如下,当变量没被volatile修饰时,主线程修改共享变量的值后并没有更新到主内存中,所以另一个线程无法读取到修改后的值导致出现死循环。

使用volatile修饰变量:

 运行结果,程序可以正常结束,

但是,如果在while循环体中加上一段输出语句,也能够停止线程,原因在哪里,看下源码

  1. public void run() {
  2. System.out.println("子线程开始.....");
  3. while (flag){
  4. System.out.println("子线程正在执行循环任务!!");
  5. }
  6. System.out.println("子线程执行结束....");
  7. }
  1. public void println(String x) {
  2. synchronized (this) {
  3. print(x);
  4. newLine();
  5. }
  6. }

 原来是因为,输出语句的内容,有一个同步代码块,进入、离开同步代码块,都会和主内存的共享变量的值保证一致,从而实现了可见性。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/266111?site
推荐阅读
相关标签
  

闽ICP备14008679号