看了 why大佬的 博客一个困扰我122天的技术问题,我好像知道答案了。

发现他留了个坑,在变量i类型为 int 或者 Integer 时,int类型的i死循环了而Integer类型的i可以结束

int类型的i,出现死循环的机会是随机的,可能需要多来几次,估计1000来次吧

代码在下面,各位大佬可以拿去测测

public class VolatileDemo {
private static boolean flag = false;
private static int i = 0;
// (3)
// private static Integer i = 0;
// (4)
// private volatile static int i = 0; public static void main(String[] args) throws InterruptedException {
new Thread(() -> {
// try {
// TimeUnit.MILLISECONDS.sleep(100);
flag = true;
// System.out.println("flag 被修改成 true");
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}).start();
while (!flag) {
i++;
// (1)
// System.out.println("flag标识 = " + flag);
// (2)
// try {
// TimeUnit.MILLISECONDS.sleep(10);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
System.out.println("程序结束,i=" + i);
} }

当时考虑的问题是 int 类型在栈上而 Integer 类型出现在堆上,一个普通类型另一个引用类型,在群里一阵讨论

最后在一个群友提示下发现了问题的关键,Integer 底层的 value用了 final修饰

final修饰变量,看过《java并发编程艺术》应该知道,它专门对final做了一个大章节的说明

最最重要的是它会添加内存屏障storestore,问题看起来是解决了

但新的问题出现了,还是看过《java并发编程艺术》的都知道,x86对写写,读写,读读内存屏障默认忽略,只对storeload有效

书本上又说道既然它加了storestore,x86无视它,那么为啥final会生效呢???

此处@why大佬过来讨论讨论到底怎么回事?

final添加内存屏障问题的更多相关文章

  1. 【C#】通过一个案例 彻底了解 Volatile和 内存屏障

    案例如下的.我个人理解是不会出现出现0,0的结果,但是很明显出现了. 说明对我对 Volatile\内存屏障\乱序排序的理解是不对. 今天就通过这个案例,理清这些概念. using System; u ...

  2. Java内存模型(MESI、内存屏障、volatile和锁及final内存语义)

    JMM (Java内存模型) Java线程的实现 实现线程主要有三种方式,Java线程从JDK1.3后采用第一种方式实现: 使用内核线程实现(1:1实现) 使用用户线程实现(1:N实现) 使用用户线程 ...

  3. JVM内存模型、指令重排、内存屏障概念解析

    在高并发模型中,无是面对物理机SMP系统模型,还是面对像JVM的虚拟机多线程并发内存模型,指令重排(编译器.运行时)和内存屏障都是非常重要的概念,因此,搞清楚这些概念和原理很重要.否则,你很难搞清楚哪 ...

  4. synchronized 与 volatile 原理 —— 内存屏障的重要实践

    单例模式的双重校验锁的实现: 第一种: private static Singleton _instance; public static synchronized Singleton getInst ...

  5. JVM内存模型、指令重排、内存屏障概念解析(转载)

    在高并发模型中,无是面对物理机SMP系统模型,还是面对像JVM的虚拟机多线程并发内存模型,指令重排(编译器.运行时)和内存屏障都是非常重要的概念,因此,搞清楚这些概念和原理很重要.否则,你很难搞清楚哪 ...

  6. [面试]volatile类型修饰符/内存屏障/处理器缓存

    volatile类型修饰符 本篇文章的目的是为了自己梳理面试知识点, 在这里做一下笔记. 绝大部分内容是基于这些文章的内容进行了copy+整理: 1. http://www.infoq.com/cn/ ...

  7. Java多线程学习笔记之三内存屏障与Java内存模型

    基本内存屏障 处理器支持那种内存重排序,就会提供能够禁止相应内存重排序的的指令,这些指令就被成为基本内存屏障:StroeLoad屏障.StroeLoad屏障.LoadLoad屏障.LoadStore屏 ...

  8. Linux内核中锁机制之内存屏障、读写自旋锁及顺序锁

    在上一篇博文中笔者讨论了关于原子操作和自旋锁的相关内容,本篇博文将继续锁机制的讨论,包括内存屏障.读写自旋锁以及顺序锁的相关内容.下面首先讨论内存屏障的相关内容. 三.内存屏障 不知读者是是否记得在笔 ...

  9. 大话Linux内核中锁机制之内存屏障、读写自旋锁及顺序锁

    大话Linux内核中锁机制之内存屏障.读写自旋锁及顺序锁 在上一篇博文中笔者讨论了关于原子操作和自旋锁的相关内容,本篇博文将继续锁机制的讨论,包括内存屏障.读写自旋锁以及顺序锁的相关内容.下面首先讨论 ...

随机推荐

  1. Scala 关键字

    Java关键字 Java 一共有 50 个关键字(keywords),其中有 2 个是保留字,目前还不曾用到:goto 和 const.true.false 和 null 看起来很像关键字,但实际上只 ...

  2. Linux进阶之排错

    Permission denied 检查selinux长时间没有响应 防火墙 nginx和httpd可以自检nginx和httpd有日志 /var/log/nginx/ /var/log/httpd/ ...

  3. Oracle和MySQL差异总结

    常用功能差异 锁差异: • Oracle锁加在数据块上 • InnoDB 是在索引上加锁,所以MySQL锁的粒度没有Oracle 精细. 导入导出: • Oracle采用EXP /IMP ,EXPDP ...

  4. 使用vue-i18n实现中英文切换(内含动态属性的绑定)

    最近做学生管理系统,因为有国外的学生,所以要进行中英文切换,查了查Vue中使用vue-i18n插件能够实现网页的中英文切换,学习内容如下: 一.下载vue-i18n插件 npm install vue ...

  5. Go基础结构与类型02---使用iota定义常量组

    package main import "fmt" /*const ( USA = 0 China = 1 Russia = 2 Britain = 3 France = 4 )* ...

  6. App自动化测试之Appium环境安装(涉及雷电模拟器和真机)

    1.安装Microsoft .NET Framework 4.5 及以上版本 2.安装Appium 官方网站地址:http://appium.io/ 我装了1.17.0版本 3.安装JDK 1.8及以 ...

  7. 重新整理 .net core 实践篇—————3种配置验证[十四]

    前言 简单整理一些配置的验证. 正文 配置的验证大概分为3类: 直接注册验证函数 实现IValidteOptions 使用Microsoft.Extensions.Options.DataAnnota ...

  8. GPU上稀疏矩阵的基本线性代数

    GPU上稀疏矩阵的基本线性代数 cuSPARSE库为稀疏矩阵提供了GPU加速的基本线性代数子例程,这些子例程的执行速度明显快于仅CPU替代方法.提供了可用于构建GPU加速求解器的功能.cuSPARSE ...

  9. ES6函数参数

    之前在看Vue2.0的时候,就被很多的箭头函数困扰,一直不知道是怎么回事,虽然箭头函数四个字在我耳边一直转圈,今天小编整理整理箭头函数里面的常见用法和表现形式,在这个Vue3.0已经到来的一段时间,希 ...

  10. selenium css定位元素

    CSS 选择器: 常见符号: #表示 id选择器 .表示 class选择器 >表示子元素,层级 一个空格也表示子元素,但是是所有的后代子元素,相当于 xpath 中的相对路径 一.css:属性定 ...