volatile关键字小结

来源:互联网 发布:数据质量系统 编辑:程序博客网 时间:2024/04/28 10:11

Java 提供了一种稍弱的同步机制,即 volatile 变量,用来确保将变量的更新操作通知到其他线程。可以将 volatile 看做一个轻量级的锁,但是又与锁有些不同:
1. 对于多线程,不是一种互斥关系
2. 不能保证变量状态的“原子性操作”

在没有用volatile关键字修饰的demo

/** * Volatile 关键字:当多线程操作共享数据时,可以保证内存数据的可见性, * 相较于synchronized来说是一种比较轻量级的同步策略。 * 注意: * 1. Volatile不能保证变量的原子性。 * 2. 不具备互斥性 * Created by 吴海飞 on 2017-1-23. */public class TestVolatile {    public static void main(String[] args){        volatileDemo volatileDemo = new volatileDemo();        new Thread(volatileDemo).start();        while (true){            if(volatileDemo.isFlag()){                System.out.println("------------------");                break;            }        }    }}class volatileDemo implements Runnable{    private boolean flag = false;    @Override    public void run() {        try {            Thread.sleep(200);        } catch (InterruptedException e) {        }        flag = true;        System.out.println("flag=" + isFlag());    }    public boolean isFlag() {        return flag;    }    public void setFlag(boolean flag) {        this.flag = flag;    }}
  • 代码运行后会出现这种状况如下图所示:

  • 出现这种状况的原因是:
    主线程与子线程并发执行,在子线程拿到flag=false的同时,主线程也拿到了flag=false,之后子线程将flag变为true,并打印出flag,结束线程。主线程因为读取到的flag = false,所以一直处于死循环状态中无法结束线程任务。

  • 具体分析如下图所示:
    这里写图片描述

  • 将flag变量设置成 volatile的,这样问题就解决了。
    当子线程将flag关键字改变时,将flag从子线程的缓冲区写入到内存中,这样主线程读到的flag变成true了,所以问题就解决了。

0 0
原创粉丝点击