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

    1. 先讲点理论的知识:

    volatile 关键字使用场景:一个线程写,多个线程读。性质:保证可见性,但不是原子性的。

    从jvm的内存模型来看,jvm线程有自己的本地内存,相当于是一个缓存。线程从主内存中取变量放到本地内存中,之后读取的都是本地内存中的值,而使用volatile修饰的变量,会强制线程从主内存中读取变量的值。

    并发编程网中写道:“本地内存是JMM的一个抽象概念,并不真实存在。它涵盖了缓存,写缓冲区,寄存器以及其他的硬件和编译器优化。”

    volatile关键字使用了memory barrier技术,线程写变量时,会把CPU cache中的内容刷到主内存中,而线程读变量时,会从主内存中读取。我的感觉是:就是不使用缓存。

     

    2. 再看看一个实际的例子:

    static boolean flag = false;
    
    public static void main(String[] args) throws InterruptedException {
        final Thread loop = new Thread(new Runnable() {
            @Override
            public void run() {
                while(!flag) {
                    System.out.println("loop thread:" + System.nanoTime());
                }
            }
        });
        Thread setter = new Thread(new Runnable() {
            @Override
            public void run() {
                flag = true;
                try {
                    loop.join(); //等循环线程执行完,再退出
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        
        loop.start();
        Thread.sleep(10);
        setter.start();
    }

    网上有帖子说,上面的代码有可能产生死循环,但可能性很小。于是写了个dos脚本,执行程序1000次,也没发生死循环,所以我的理解是,loop线程并不会产生死循环,只是不能及时地读取到 flag 的值。

    @echo off
    for /l %%i in (1,1,1000) do (
      @echo start ...
      java -jar volatile.jar
    )
    pause

    那么,实现共享变量的可见性,除了volatile关键字外,还有其他方式吗?答案是synchronized关键字和Lock,网上说在释放锁时,会把共享变量的值刷新到主内存。

    3. 结合 AtomicInteger 谈 volatile

    private volatile int value;

    AtomicInteger类的value字段是volatile的,这个类的作用是:在不加锁的情况下,去实现并发读写共享变量。

    假定value没有用volatile修饰,这时一个线程使用cas修改值成功,但是因为没有加锁,value值不会刷到主存中,其他线程就有可能读取到缓存值(并未修改的值)。

  • 相关阅读:
    链表
    链式学习法:提升技术深度
    数组
    写点什么
    7 天掌握算法面试必考知识点: 作业安排及如何提交
    创建Mac OS root账户
    正则表达式匹配及替换
    Xcode 10 之New Build System & Legacy Build System 旧版构建系统
    性能指标:TPS、QPS、RT、吞吐量
    Objective-C和Swift语言特性
  • 原文地址:https://www.cnblogs.com/allenwas3/p/6626131.html
Copyright © 2011-2022 走看看