zoukankan      html  css  js  c++  java
  • volatile关键字小结

    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了,所以问题就解决了。

  • 相关阅读:
    中国剩余定理(普通+扩展)
    因子和(洛谷P1593)——约数和+分解质因数
    暑假考试题6:problem 题(Catlan + dp + 组合数)
    暑假考试题6:single 单(树上推理)
    暑假考试题5:tree 最小生成树(最小生成树+倍增)
    暑假考试题5:序列(分类讨论水题)
    暑假考试题5:工作 work(贪心+二分)
    暑假考试题4:砍树 cut(整除分块)
    4.8 作业
    面向对象编程
  • 原文地址:https://www.cnblogs.com/haifeiWu/p/9079586.html
Copyright © 2011-2022 走看看