V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zhao1014
V2EX  ›  Java

到底什么才是对象发布?为什么逸出会产生线程安全问题?

  •  
  •   zhao1014 · 2020-12-21 15:13:12 +08:00 · 1846 次点击
    这是一个创建于 1464 天前的主题,其中的信息可能已经有所发展或是发生改变。

    看了书上说的概念有点模糊不清,最好是能用代码举例说明,谢谢大佬们!

    11 条回复    2020-12-25 09:50:09 +08:00
    zoharSoul
        1
    zoharSoul  
       2020-12-21 15:49:04 +08:00
    没听说过这两个词....

    带点上下文呗?
    Chinsung
        2
    Chinsung  
       2020-12-21 18:09:13 +08:00
    什么书啊。。。。没听过这个概念。
    第二个到时候有沾点边的,好像是指的某个对象本身不是 thread safe 的,但是因为一些编程上的错误导致其他线程可以访问到,导致线程安全问题吧。
    zhao1014
        3
    zhao1014  
    OP
       2020-12-21 18:23:29 +08:00
    @zoharSoul
    @Chinsung
    是的,并发编程相关。我看的书是《 Java 多线程编程实战指南》作者:黄文海,在《 Java 并发编程实战》中也有对象发布和逸出的概念。

    又重新翻了一下书,感觉已经大致理解了。

    一个对象可被作用域之外的代码获取就称为对象发布,例如创建了一个私有成员,但在 public
    方法中作为返回值返回。

    多线程环境中对象发布的问题在于,可能存在两个线程,一个线程创建了该类的对象,而另一个线程则通过发布渠道(例如上述的 public 方法)访问该对象的成员。

    如果 JIT 或 处理器执行了指令重排序,导致成员的初始化被重排序到引用赋值之后,那么第二个线程使用该对象时,该对象还没有初始化完毕,即该对象的成员可能为 null (默认值)
    chendy
        4
    chendy  
       2020-12-21 18:31:00 +08:00
    这个翻译一看就是《 Java 并发编程实践》……
    原文:
    **Publishing** an object means making it available to code outside of its current scope
    An object that is published when it should not have been is said to have **escaped**
    把对象给别人用就是“发布”,把不该发布的东西发布了就叫“逃逸”
    举个例子:Collections.synchronizedCollection 会“发布”一个线程安全的 Collection,但是如果代码里有其他地方还能访问和操作其内部线程不安全的 Collection,就叫“逃逸”
    zhao1014
        5
    zhao1014  
    OP
       2020-12-21 18:31:20 +08:00
    @zoharSoul
    @Chinsung
    对象的初始化 和 对象的使用 由两条线成同时执行
    zhao1014
        6
    zhao1014  
    OP
       2020-12-21 18:32:38 +08:00
    @chendy 实际上是这本《 Java 多线程编程实战指南》
    hyqCrystal
        7
    hyqCrystal  
       2020-12-22 09:23:48 +08:00
    我的理解 对象发布理解为 提供外界可访问的实例对象
    可以是静态初始化对象 也可以提供方法返回对象 等

    发布实例对象 提供外界访问
    thinkmore
        8
    thinkmore  
       2020-12-22 10:25:14 +08:00
    应该是对象安全发布。


    比如你写了一个方法返回 List<User>,然后其他人对这个集合中的对象做了修改,而你也在使用这个集合中的 user,就会导致他的修改影响了你的数据。

    这就是逃逸。


    那么如何安全发布呢?

    还是上面那个例子,你可以返回 Collections.unmonifiedList 或者根据你的业务情况进行具体操作
    thinkmore
        9
    thinkmore  
       2020-12-22 10:28:06 +08:00
    https://generalthink.github.io/2016/09/21/talk-thread-safe/ 可以参考下我这篇博客中安全的发布对象那一部分
    zhao1014
        10
    zhao1014  
    OP
       2020-12-22 11:04:35 +08:00 via Android
    @thinkmore 不戳,jvm 与 硬件的联系学到了,图片我可以用到自己的笔记里吗?
    thinkmore
        11
    thinkmore  
       2020-12-25 09:50:09 +08:00
    @zhao1014 可以的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3025 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 14:18 · PVG 22:18 · LAX 06:18 · JFK 09:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.