并发编程之volatile (JMM内存可见性,不保证原子性,禁止指令重排)

本文深入探讨了Java内存模型(JMM)中的可见性问题,重点介绍了volatile关键字的作用。volatile保证了线程间的变量可见性,但不保证原子性,且能防止指令重排,以确保多线程环境下的顺序性。文中通过实例分析了volatile在单例模式中的应用及其可能存在的线程安全问题,并强调了其在并发编程面试中的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

1.可见性

一.了解JMM可见性需先知道主内存与工作内存的关系

二.volatile可见性

2.不保证原子性

3.禁止指令重排

指令重排理解

volatile禁止指令重排

4.使用场景分析(单例模式双端检锁机制怎么也存在线程安全问题)


 可见性,原子性,顺序性是并发编程三要素。volatile能够实现可见性,不能保证原子性,禁止指令重排保证了顺序性,在并发编程种非常常见,面试中也是常客。面试官往往会说聊下对volatile理解,当你回答完第一个问题,接下来将是接连的炮轰。

   下面将从并发要素对volatile进行深入理解,懂的原理了,就可以应对相关面试的变种

1.可见性

一.了解JMM可见性需先知道主内存与工作内存的关系

     由于 CPU 的处理速度很快,相比之下,内存的速度就显得很慢,所以为了提高 CPU 的整体运行效率,减少空闲时间,在 CPU 和内存之间会有 cache 层,也就是缓存层的存在。虽然缓存的容量比内存小,但是缓存的速度却比内存的速度要快得多,其中 L1 缓存的速度仅次于寄存器的速度。结构示意图如下所示:

         

 

                                        (图-1)

Java 作为高级语言,只需要关心 JMM 抽象出来的主内存和工作内存的概念。为了更方便你去理解,可参考下图:

 

                                     (图-2)

上述的图用我们日常的大白话说就是:多个线程需要去使用共享变量,但是规范是每个线程只能够直接接触到工作内存,无法直接操作主内存,而工作内存中所保存的正是主内存的共享变量的副本,主内存和工作内存之间的通信是由 JMM 控制的。

 JMM 有以下规定:

(1)所有的变量都存储在主内存中,同时每个线程拥有自己独立的工作内存,而工作内存中的变量的内容是主内存中该变量的拷贝;

(2)线程不能直接读 / 写主内存中的变量,但可以操作自己工作内存中的变量,然后再同步到主内存中,这样,其他线程就可以看到本次修改;

(3) 主内存是由多个线程所共享的,但线程间不共享各自的工作内存,如果线程间需要通信,则必须借助主内存中转来完成。

二.volatile可见性

 通过分析  (图-2)可能引发不同的副本变量在彼此线程不可见行问题,也就是说线程修改 自己内存的副本变量的值其它线程不能立马感应到。 如果主内存中的共享变量加了volatile修饰,可保证线程之间变量修改了彼此可感知到。

如下例子阐释加不加volatile的区别:

不加volatile,修改了change()方法内的值,主内存的变量无法感知到

package com.yang;

import java.util.concurrent.TimeUnit;

public class TestVolatile {

    int  x = 0;

    public void change() {

        this.x = 1;

    }

    public static void main(String[] args) {

        // 资源类

        TestVolatile myData = new TestVolatile();

        // AAA线程 实现了Runnable接口的,lambda表达式

        new Thread(() -> {

            System.out.println(Thread.currentThread().getName() + "\t come in");

            // 线程睡眠3秒,假设在进行运算

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值