看《Java并发编程实战》遇到如下问题

代码:

/**
* Created by yesiming on 16/11/11.
*/
public class Holder {
private int n; public Holder(int n) {
this.n = n;
} public void assertSanity() {
if(n != n) {
throw new AssertionError("This statment is false.");
}
}
} 疑问是:assertSanity() 方法中的判断 n != n
n它怎么就能不等于n呢,它们是同一个变量呀 解惑:设想一下场景
有2个线程 A,B
A做的操作:Holder holder = new Holder(42);
B做的操作:
if(holder != null) {
  holder.assertSantiy();
}
对于线程A的操作,jvm执行时的步骤:1.栈里生成holder引用,2.执行构造函数,在堆里生成Holder的内存空间,并且给n赋值为42,3.把holder指向堆里生成的内存空间
问题是:上面的1,2,3步骤不是按照1,2,3的顺序执行的,执行引擎对指令重排序后,可能会按照1,3,2的顺序执行,也可能是别的顺序
结果:这样就导致当holder指向了堆里的内存空间时(这时holder不是null了),但是构造函数执行尚未完成,n还没有被赋值为42。 对于线程B的操作,assertSanity()方法编译后的指令如下:

public void assertSanity();
flags: ACC_PUBLIC
Code:
stack=3, locals=1, args_size=1
0: aload_0
1: getfield #2 // Field n:I
4: aload_0
5: getfield #2 // Field n:I
8: if_icmpeq 21
11: new #3 // class java/lang/AssertionError
14: dup
15: ldc #4 // String This statment is false.
17: invokespecial #5 // Method java/lang/AssertionError."<init>":(Ljava/lang/Object;)V
20: athrow
21: return
LineNumberTable:
line 14: 0
line 15: 11
line 17: 21
LocalVariableTable:
Start Length Slot Name Signature
0 22 0 this Lo1/Holder;
}

注意看绿色部分的指令,
第一步:1: getfield #2 // Field n:I
取得n的值
第二部:5: getfield #2 // Field n:I
取得n的值
也就是说,在执行比较指令if_icmpeq之前,要让比较的两个数都进栈,然后做比较
那么,既然要进栈2次,也就可以推导出,当线程B操作第一步getField时,n没有被线程A赋值,那么这个n是0,之后,线程A修改了n的值,第二次进栈时,n的值已经是修改后的42了
这样,就会导致栈顶2个slot中的数,一个0,一个是42,必然会导致8: if_icmpeq的结果为真 解决方案:
把n定义成final,并且在声明Holder时,使用valetile关键字
final能保证Holder在构造方法执行时,不会被执行引擎重排序,也就不会出现holder指向了Holder构造产生的内存空间,但是构造方法没有执行完成的情况(n没有被赋值)
valetile保证了在外部程序中,线程A和线程B对Holder的更新状态是随时可见的

Java安全发布的理解的更多相关文章

  1. Java语言的个人理解

    Java语言的个人理解(比价深层次吧) 大四的生活确实十分的奢靡,不锻炼,不读书,几乎就是当一天和尚撞一天钟的生活,太颓废了,还好自己不是这个样子,不过身体确实差了很多,昨天跑了一圈内环(4KM),今 ...

  2. Java常量字符串String理解

    Java常量字符串String理解 以前关于String的理解仅限于三点:1.String 是final类,不可继承2.String 类比较字符串相等时时不能用“ == ”,只能用  "eq ...

  3. java的final变量理解

    java的final变量理解 final基本类型是数值不能改变 final对象是引用不能改变,对象其自身是可以被修改的.

  4. 谈谈我对Java中CallBack的理解

    谈谈我对Java中CallBack的理解 http://www.cnblogs.com/codingmyworld/archive/2011/07/22/2113514.html CallBack是回 ...

  5. Gradle 1.12用户指南翻译——第46章. Java 库发布插件

    本文由CSDN博客貌似掉线翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...

  6. java项目发布到linux服务器,tomcat正常启动但没加载项目

    问题描述: java项目发布到linux服务器,一切操作正确,linux命令启动tomcat后,查看日志启动tomcat正常,上传的war包已经解压成功,但是tomcat没加载项目. 解决方法: 1. ...

  7. 【Java】「深入理解Java虚拟机」学习笔记(1) - Java语言发展趋势

    0.前言 从这篇随笔开始记录Java虚拟机的内容,以前只是对Java的应用,聚焦的是业务,了解的只是语言层面,现在想深入学习一下. 对JVM的学习肯定不是看一遍书就能掌握的,在今后的学习和实践中如果有 ...

  8. Java提高篇之理解java的三大特性——继承

    在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句 ...

  9. 【转】java提高篇(二)-----理解java的三大特性之继承

    [转]java提高篇(二)-----理解java的三大特性之继承 原文地址:http://www.cnblogs.com/chenssy/p/3354884.html 在<Think in ja ...

随机推荐

  1. Java socket 说明 以及web 出现java.net.SocketException:(Connection reset或者Connectreset by peer:Socket write error)的解释

    另外http://www.cnblogs.com/fengmk2/archive/2007/01/15/using-Socket.html可供参考   一Java socket 说明 所谓socket ...

  2. c++实现委托

    #include "stdafx.h" #include <iostream> #include <string> using namespace std; ...

  3. bzoj 1208 宠物收养所--splay

    这个题也是单点维护,不管来的是人还是狗,只要num=0就插入,否则就删除. // File Name: ACM/bzoj/1208.cpp // Author: Zlbing // Created T ...

  4. 【效率】FIND

    文档 HTML Flash CSS 字体 命名颜色 工具 IMG

  5. 数据结构(跳跃表):NOI 2004 郁闷的出纳员

    郁闷的出纳员 [问题描述] OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常, ...

  6. 洛谷2583 地铁间谍 (UVa1025A Spy in the Metro)

    洛谷2583 地铁间谍(UVa1025A Spy in the Metro) 本题地址:http://www.luogu.org/problem/show?pid=2583 题目描述 特工玛利亚被送到 ...

  7. 最小生成树——[HAOI2006]聪明的猴子

    题目:[HAOI2006]聪明的猴子 描述: [题目描述] 在一个热带雨林中生存着一群猴子,它们以树上的果子为生.昨天下了一场大雨,现在雨过天晴,但整个雨林的地表还是被大水淹没着, 猴子不会游泳,但跳 ...

  8. openStack 云平台管理节点管理网口流量非常大 出现丢包严重 终端总是时常中断问题调试及当前测试较有效方案

    tuning for Data Transfer hosts connected at speeds of 1Gbps or higher <一.本次OpenStack系统调试简单过程简单记录& ...

  9. 实时控制软件第一次作业--CNC软件系统分析

    作者:李君威U201310747 一.该系统有哪些强实时功能需求?需要对哪些实时事件进行实时响应,对允许的实时延迟的数量级进行估计. 答:在数控系统中,位置控制.插补计算.紧急控制等严格实时性任务需要 ...

  10. iframe与父页面中JS执行顺序控制

    同事遇到了一个问题: 父页面中有几个iframe,初衷是父页面的JS通过AJAX获取数据,然后用于初始化iframe页面,可以结果却是有的iframe页面却不能获得数据. [问题根源] 父页面在加载i ...