java并发原理实战(6) -- volatile的原理理解

简介: java并发原理实战(6) -- volatile的原理理解

volatile原理理解


引子


看一段代码:

public class Demo {
    private int a= 1;
    public int getA() {
        return a;
    }
    public void setA(int a) {
        try {
            Thread.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.a = a;
    }
    public static void main(String[] args) {
        Demo demo = new Demo();
        new Thread(
                () -> {
                    demo.setA(10);
                }
        ).start();
        new Thread(
                () -> {
                    System.out.println(demo.getA());
                }
        ).start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("最终的值为=="+ demo.a);
    }
}


运行结果:


1dc618a0ed9580ce8bfa6facb208c08f.png


发现,结果并不相同。


解决方式1:

5d4c6812c8535adbb050f4ddf2e1bce8.png


运行结果:


46a9d80a6e05e4e3b19d57a0ee70bcdf.png


除此以外,还有一种方式,用volatile:

66ba272a0bfc97be54a5fa679e3d5482.png

public class Demo {
    private volatile int a = 1;
    public int getA() {
        return a;
    }
    public void setA(int a) {
        try {
            Thread.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.a = a;
    }
    public static void main(String[] args) {
        Demo demo = new Demo();
        new Thread(
                () -> {
                    demo.a = 10;
                }
        ).start();
        new Thread(
                () -> {
                    System.out.println(demo.a);
                }
        ).start();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("最终的值为==" + demo.a);
    }
}


运行结果:


1dc618a0ed9580ce8bfa6facb208c08f.png


volatile的原理:


深入理解Volatile关键字及其实现原理


5d4c6812c8535adbb050f4ddf2e1bce8.png


工作内存Work Memory其实就是对CPU寄存器和高速缓存的抽象,或者说每个线程的工作内存也可以简单理解为CPU寄存器和高速缓存。


那么当写两条线程Thread-A与Threab-B同时操作主存中的一个volatile变量i时,Thread-A写了变量i,那么:


Thread-A发出LOCK#指令

发出的LOCK#指令锁总线(或锁缓存行),同时让Thread-B高速缓存中的缓存行内容失效

Thread-A向主存回写最新修改的i

Thread-B读取变量i,那么:


Thread-B发现对应地址的缓存行被锁了,等待锁的释放,缓存一致性协议会保证它读取到最新的值

由此可以看出,volatile关键字的读和普通变量的读取相比基本没差别,差别主要还是在变量的写操作上。


46a9d80a6e05e4e3b19d57a0ee70bcdf.png


lock指令


1dc618a0ed9580ce8bfa6facb208c08f.png


什么时候使用volatile


5d4c6812c8535adbb050f4ddf2e1bce8.png



相关文章
|
5天前
|
缓存 安全 Java
Java中的并发容器:ConcurrentHashMap详解
Java中的并发容器:ConcurrentHashMap详解
|
4天前
|
并行计算 Java API
Java中的函数式编程实战与Lambda表达式应用
Java中的函数式编程实战与Lambda表达式应用
|
4天前
|
分布式计算 Java 大数据
实战:基于Java的大数据处理与分析平台
实战:基于Java的大数据处理与分析平台
|
4天前
|
存储 负载均衡 Java
Java中的服务注册与发现原理与实现
Java中的服务注册与发现原理与实现
|
4天前
|
监控 搜索推荐 Java
实战:基于Java的实时数据流处理平台
实战:基于Java的实时数据流处理平台
|
5天前
|
存储 监控 安全
深入理解Java虚拟机(JVM)原理
深入理解Java虚拟机(JVM)原理
|
5天前
|
安全 Java 调度
Java并发编程:从基础到实战
【7月更文挑战第3天】在Java的世界中,并发编程是一块充满挑战与机遇的领域。本文将带领读者从理解并发编程的基本概念开始,逐步深入到Java并发工具的使用和高级技巧的应用。我们将一起探索如何在多线程环境下保证数据的一致性和程序的正确性,以及如何通过高效的并发策略来提升应用性能。准备好,让我们开启Java并发编程的旅程,掌握让应用飞一般运行的秘密。
16 1
|
5天前
|
并行计算 Java API
Java中的并发工具类详解
Java中的并发工具类详解
|
3天前
|
存储 Java 程序员
Java内存模式以及volatile关键字的使用
Java内存模式以及volatile关键字的使用
8 0
|
3天前
|
Java 调度 Windows
Java面试之程序、进程、线程、管程和并发、并行的概念
Java面试之程序、进程、线程、管程和并发、并行的概念
8 0