zoukankan      html  css  js  c++  java
  • final添加内存屏障问题

    看了 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大佬过来讨论讨论到底怎么回事?

  • 相关阅读:
    .NET实时2D渲染入门·动态时钟
    JAVA中抽象类的使用
    R语言中函数调试
    利用Bioperl的SeqIO模块解析fastq文件
    ASCII码表
    JAVA 中转义符的理解
    在线引物设计网站,老板推荐的,亲测好用
    列出一个买东西的好网站,值得推荐
    R语言集合操作
    R语言do.call 函数用法详解
  • 原文地址:https://www.cnblogs.com/bangiao/p/13180028.html
Copyright © 2011-2022 走看看