码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 面试题:volatile能否保证线程安全


    目录

    • 目的
    • 资源
    • 如何理解线程安全
    • 线程安全要考虑的3个方面
      • 可见性
      • 有序性
      • 原子性
    • 示例代码验证
      • volatile 不能保证原子性
      • volatile 可保证可见性
      • volatile设置内存屏障保证有序性(难理解)

    目的

    方便后续自己复习方便, 也是一次学习的记录.

    资源

    B站的一个讲高频面试题的一个学习视频

    如何理解线程安全

    参考: 什么是线程安全

    线程安全要考虑的3个方面

    可见性

    一个线程对共享变量修改, 另一个线程可以看到最新的结果

    有序性

    一个线程内代码按照编写顺序执行, 没有指令重排的影响

    原子性

    一个线程内多行代码以一个整体运行, 期间不能有其他线程的代码插队. 没有线程切换的影响.

    示例代码验证

    volatile 不能保证原子性

    /**
     * volatile原子性例子: 不能保证原子性
     * 

    * 调试需要拆解"balance -= 5;" 使用Debug模式复现 * * @author xiaozhengN 571457082@qq.com * @since 2022-11-19 18:09:41 **/ @Slf4j public class AddAndSubtract { static volatile int balance = 10; private static void subtract() { balance -= 5; } private static void add() { balance += 5; } public static void main(String[] args) throws InterruptedException { CountDownLatch latch = new CountDownLatch(2); new Thread(() -> { subtract(); latch.countDown(); }).start(); new Thread(() -> { add(); latch.countDown(); }).start(); latch.await(); log.info("共享变量balance: {}", balance); } }

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    volatile 可保证可见性

    /**
     * volatile 可见性例子
     *
     * -Xint
     *
     * @author xiaozhengN 571457082@qq.com
     * @since 2022-11-19 17:36:20
     **/
    @Slf4j
    public class ForeverLoop {
    
        // 共享变量, 控制 foo() 循环次数
        static volatile boolean isStop = false;
    
        public static void main(String[] args) {
            new Thread(() -> {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    log.error("", e);
                }
                isStop = true;
                log.info("修改共享变量成功: isStop: {}", isStop);
            }).start();
    
            new Thread(() -> {
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    log.error("", e);
                }
                log.info("从主内存中获取共享变量, isStop: {}", isStop);
            }).start();
            foo();
        }
    
        static void foo() {
            int i = 0;
            while (!isStop) {
                i++;
            }
            log.info("foo方法已结束, 循环次数为: {}", i);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    volatile设置内存屏障保证有序性(难理解)

    /**
     * volatile 有序性例子
     * 

    * 没有测试成功, 报错: Unrecognized VM option 'StressCCP' * java -XX:+UnlockDiagnosticVMOptions -XX:+LogCompilation -jar jcstress.jar -t main.daily.Reordering.Case1 * D:\17-JDKS\jdk-16.0.1\bin\java -XX:+UnlockDiagnosticVMOptions -XX:+LogCompilation -jar jcstress.jar -t main.daily.Reordering.Case1 * * @author xiaozhengN 571457082@qq.com * @since 2022-11-19 18:27:03 **/ public class Reordering { @JCStressTest @Outcome(id = {"0, 0", "1, 1", "0, 1"}, expect = Expect.ACCEPTABLE, desc = "可接受的值") @Outcome(id = "1, 0", expect = Expect.ACCEPTABLE_INTERESTING, desc = "感兴趣的值(发生指令重排)") @State public static class Case1 { int x; int y; @Actor public void actor1() { x = 1; y = 1; } @Actor public void actor2(II_Result result) { result.r1 = y; result.r2 = x; } } @JCStressTest @Outcome(id = {"0, 0", "1, 1", "0, 1"}, expect = Expect.ACCEPTABLE, desc = "可接受的值") @Outcome(id = "1, 0", expect = Expect.FORBIDDEN, desc = "被禁止的值") @State public static class Case2 { int x; volatile int y; @Actor public void actor1() { x = 1; y = 1; } @Actor public void actor2(II_Result result) { result.r1 = y; result.r2 = x; } } @JCStressTest @Outcome(id = {"0, 0", "1, 1", "0, 1"}, expect = Expect.ACCEPTABLE, desc = "可接受的值") @Outcome(id = "1, 0", expect = Expect.ACCEPTABLE_INTERESTING, desc = "感兴趣的值(发生指令重排)") @State public static class Case3 { volatile int x; int y; @Actor public void actor1() { x = 1; y = 1; } @Actor public void actor2(II_Result result) { result.r1 = y; result.r2 = x; } } }

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
  • 相关阅读:
    主流音视频芯片交叉编译工具链版本
    【算法】树形DP③ 监控二叉树 ⭐(二叉树染色&二叉树灯饰)!
    鸿蒙(API 12 Beta2版)媒体开发【使用OHAudio开发音频播放功能(C/C++)】
    计算机毕业设计springboot+vue基本微信小程序的汽车租赁公司小程序
    计算机毕业设计ssm+vue基本微信小程序的电影票务系统-电影票预订系统
    【Python基础】对Python的深入认识以及各种情况的报错汇总
    @AliasFor注解详解(结合源码分析)
    隐藏label标签中指定文字
    经济型EtherCAT运动控制器(十):EtherCAT总线快速入门
    Office技巧(持续更新)(Word、Excel、PPT、PowerPoint、连续引用、标题、模板、论文)
  • 原文地址:https://blog.csdn.net/xiaozhengN/article/details/127947647
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号