java多线程之volatile总结

java内存模型

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

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

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

看代码:

class VolatileDemo extends Thread{
    public boolean flag = true;

    public void setFlag(boolean flag){
        this.flag = flag;
    }

    @Override
    public void run() {
        System.out.println("子线程开始.....");
        while (flag){
        }
        System.out.println("子线程执行结束....");
    }
}

public class ThreadVolatileDemo {
    public static void main(String[] args) throws InterruptedException {
        VolatileDemo volatileDemo = new VolatileDemo();
        volatileDemo.start();
        Thread.sleep(1000);
        volatileDemo.setFlag(false);
        System.out.println("flag已经修改为false!");
        Thread.sleep(1000);
        System.out.println("flag==="+volatileDemo.flag);

    }
}

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

使用volatile修饰变量:

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

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

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值