03 对象的共享

对象的共享

3.1 可见性:

通常,我们无法确保执行读操作的线程能适时的看到其他线程写入的值,为了确保多个线程之间对内存写入操作的可见性,必须使用同步机制;

重排序:

在没有同步的的情况下,编译器、处理器以及运行时等都可能对操作的执行顺序进行一些意向不到的调整,JVM可以保证在单线程内,程序表现为串行语义(并非没有重排序,只是不影响结果);因为重排序是一种优化手段,能提升程序执行效率,所以为此牺牲一些易用性是值得的;

3.1.1 失效数据:

  1. 在缺乏同步的程序中,读线程获得的变量可能是失效值,如读多个变量,则可能一部分失效,一部分是最新值;某些失效值可能关系不大,但链表中的引用失效,情况就会非常复杂;

3.1.2 非原子的64位操作:

  1. 非原子的64位操作:当线程没有同步的情况下读取变量,可能会得到一个失效值,但至少这个值是之前某个线程设置的值,而不是一个随机值,这种安全性保证被称为最低安全性;最低安全性适用于绝大多数变量,但是存在一个例外:

    非volatile类型的64位数值变量(double和long);java内存模型要求,变量的读取和写入操作都是原子操作,但对于非volatile类型的double和long变量,JVM允许将64位的读操作和写操作分解为两个32位操作,这意味着,对他们的读取很可能读取到某个值的高32位和另一个值的低32位,因此,及时不考虑失效数据的我呢提,在并发程序中使用共享的可变的long和doulbe等类型变量也是不安全的,除非使用关键字volatile来声明他们或者用锁保护起来;HotSpot虚拟机的实现可能并未拆分为2个32位操作,但我们编程还是遵循规范而非针对实现比较好;

3.1.3加锁与可见性:

加锁的含义不仅仅体现在互斥行为,还包括内存可见性。为了确保所有的线程都能看见共享变量的最新值,所有的执行读操作和写操作的线程都必须在同一个锁上同步;

3.1.4 volatile变量:

volatile:

  1. volatile的正确使用方式:

    1. 确保自身的可见性;
    2. 确保他们所引用对象的状态的可见性
    3. 标识一些重要的程序生命周期事件的发生(如,初始化或关闭,线程退出等);
  2. 加锁操作既能确保可见性,又能确保原子性,而volatile只能确保可见性;

调试tips:

对于服务器应用程序,无论在开发阶段还是在测试阶段,当启动JVM时,一定都要指定-server命令行选项,server模式比client模式的JVM进行更多的优化, 如将循环内部未被修改的变量提升到循环外部,因此在开发环境中正确运行的代码可能会在部署环境中运行失败;如下程序:

    volatile boolean interruptted = false;
    while(!interruptted){
        //do something
    }

如果疏忽写漏了volatile,client模式JVM可能会表现正常,但server模式下,程序很有可能死循环;在应用环境中解决死循环问题的代价要大得多;

3.2 发布与逸出

定义:

发布一个对象的意思是指,使对象能够在当前作用于之外的代码中使用,例如,将一个指向该对象的引用保存到其他代码可以访问的地方,或者在一个非私有的方法中返回该引用,或者将引用传递到其他类的方法中;许多情况下,我们需要发布某个对象,但如果发布时要确保线程安全,则可能需要同步;发布内部状态可能会破坏封装性。当某个不应该发布的对象被发布时,这种情况就叫逸出;

发布一个对象:

当发布某个对象时,可能会间接地发布其他对象;该对象的非私有域所引用的对象和非私有方法调用达到其他对象,那这些对象也都会被发布,如发布引用类型数组对象,那么该数组中所有的引用对象都被发布;

隐式的this引用逸出:向外发布非静态内部类同时会隐式地将this发布出去,如果该操作在构造函数中,这将会把未构造完成的对象发布出去,类似的情况还存在于构造函数中调用可以被重写的方法,该方法在子类中被重写,那么实例化子类对象时,父类的初始化操作将访问还未被初始化的子类对象;

假定有一个类C,外部方法指行为不完全由C来控制的方法,包括其他类中定义的方法及C中可以被改写的方法,当把一个对象传递给某个外部方法时,就相当于发布了这个对象;不管外部方法将如何使用该对象,一旦某个对象逸出,我们都必须假设有某个类或者线程可能会吴用该对象,这正是使用封装的原因;就如同账号密码在网上被人发布,不管别人是否会恶意使用个人信息,但我们的账户都已经不再安全;

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容