看了 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. mysql基础之查询缓存、存储引擎

    一.查询缓存 "查询缓存",就是将查询的结果缓存下载,如果查询语句完全相同,则直接返回缓存中的结果. 如果应用程序在某个场景中,需要经常执行大量的相同的查询,而且查询出的数据不会经 ...

  2. mysql基础之mariadb对表中数据的增删改查

    复习: 查看表:show tables; 创建表:create table 表名(字符类型); 删除表:drop table 表名; 对表的结构进行增删改查: 查看表结构:desc 表名; 修改表-添 ...

  3. centos7 Nacos+Elasticsearch+SkyWalking

    安装包下载 nacos 下载地址:https://github.com/alibaba/nacos/releases es 下载地址:https://www.elastic.co/cn/downloa ...

  4. Centos7 Samba共享服务搭建

    Centos7 Samba共享服务搭建 1.安装启动和端口 ---------------------------------------------------------------------- ...

  5. sizeof 的妙用

    (1)sizeof也可以对一个函数调用求值,其结果是函数返回类型的大小,函数并不会被调用.

  6. 阿里云AIoT云端一体:迎接云原生+低代码时代的到来

    距上次2019年参加上海阿里云开发者大会已经近2年的时间了,也许因为疫情的原因,这一两年线下大型活动基本很少了,这次在北京国家会议中心举办的阿里云开发者大会,无论是参会人员的规模,还有演讲嘉宾的级别和 ...

  7. 【RMAN】使用RMAN备份将数据库不完全恢复到指定时间点

    RMAN作为Oracle强大的备份恢复工具,可以协助我们恢复数据库到指定时间点,这便是Oracle不完全恢复的一种体现,通过这种方法可以找回我们曾经丢失的数据.这里以找回误TRUNCATE表数据为例给 ...

  8. TensorFlow常用Python扩展包

    TensorFlow常用Python扩展包 TensorFlow 能够实现大部分神经网络的功能.但是,这还是不够的.对于预处理任务.序列化甚至绘图任务,还需要更多的 Python 包. 下面列出了一些 ...

  9. 计算机网络-vlan划分

    1.VLAN的划分 (1)基于端口的VLAN: 交换机A上的1,2端口和交换机B上的3,4端口构成一个VLAN. 交换机A上的3,4端口和交换机B上的1,2端口构成一个VLAN. (2)基于MAC地址 ...

  10. 使用BootstrapVue相关组件,构建Vue项目界面

    基于Vue的前端框架有很多,Element算一个,而BootstrapVue也可以非常不错的一个,毕竟Bootstrap也是CSS中的大佬级别的,它和Vue的整合,使得开发起来更加方便了.Bootst ...