wahahahql 2019-04-03 11:21 采纳率: 0%
浏览 383
已结题

Java中final域的内存语义问题

写final域时的重排序规则会使编译器在final域的写之后,构造函数return之前插入一个StoreStore屏障,那么下面这段程序的可能执行顺序中,为什么会出现写普通域i重排序到了StoreStore屏障之后呢?

public class FinalExample {
    int i;                            // 普通变量 
    final int j;                      //final 变量 
    static FinalExample obj;

    public FinalExample () {     // 构造函数 
        i = 1;                        // 写普通域 
        j = 2;                        // 写 final 域 
    }

    public static void writer () {    // 写线程 A 执行 
        obj = new FinalExample ();
    }

    public static void reader () {       // 读线程 B 执行 
        FinalExample object = obj;       // 读对象引用 
        int a = object.i;                // 读普通域 
        int b = object.j;                // 读 final 域 
    }
}

图片说明

PS:个人结合《Java并发编程》一书中前面对volatile内存语义的解读,对内存屏障的理解是:内存屏障能够禁止屏障前面所有的操作与屏障后面所有的操作进行重排序,例如:StoreStore屏障禁止它前面的所有写操作与它后面的写操作进行重排序。

  • 写回答

2条回答 默认 最新

  • 毕小宝 博客专家认证 2019-04-03 13:55
    关注

    首先,你这段代码就有语法错误啊,无法通过编译,你定义了一个与类名称同名的void函数,应该是构造函数的吧。
    其次,指令重拍是java编译器对代码进行的一种优化,如果我的猜的没错,去掉构造函数前的void后代码通过编译,javap查看字节码:
    图片说明

    构造函数中的初始化语句的过程跟代码顺序是一致的啊,读也是一致的。
    你自己用javap -c FinalExample 分析下字节码看看。

    最后一点是我的理解,final貌似跟指令重排没有多大的关联吧。

    评论

报告相同问题?

悬赏问题

  • ¥30 python代码,帮调试
  • ¥15 #MATLAB仿真#车辆换道路径规划
  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条