本文介绍了安全发布对象的最终vs易失性担保的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

摘自《 Java并发实践》:

From the book Java concurrency in practice :

  • 从静态初始化程序初始化对象引用

  • Initializing an object reference from a static initializer

将对其的引用存储到volatile字段或AtomicReference

Storing a reference to it into a volatile field or AtomicReference

将对其的引用存储到适当构造的最终字段中 对象

Storing a reference to it into a final field of a properly constructed object

将对其的引用存储到由a
适当保护的字段中 锁定.

Storing a reference to it into a field that is properly guarded by a
lock.

我的问题是:

  1. 要点2和3之间有什么区别?我对volatile方法和final方法之间在对象的安全发布方面的区别感兴趣.
  2. 第3点中正确构造的对象的最终字段 是什么意思?在开始要点之前,作者已经提到他们正在谈论一个正确构造的对象(我认为不会让this引用转义).但是他们又为什么提到适当构造的对象?
  1. What are the the differences between bullet points 2 and 3 ? I am interested in the difference between volatile approach and final approach in terms of safe publication of the object .
  2. What does he mean by final field of a properly constructed object in point 3 ? Before starting the bulleted points authors already mentioned that they are talking about a properly constructed object (which I assume is not letting the this reference to escape ). But once again why did they mention about properly constructed objects ?

推荐答案

  • volatile基本上意味着对该字段的任何写入将在其他线程中可见.因此,当您将字段声明为volatile:private volatile SomeType field;时,可以保证,如果构造函数写入该字段:field = new SomeType();,则随后尝试读取field的其他线程将看到此分配.
  • final的语义非常相似:如果有一个final字段,则可以保证:private final SomeType field;对该字段的写入(无论是在声明中还是在构造函数中):field = new SomeType();不会被重复如果该对象已正确发布,则其他线程将显示 (例如,this不能转义).
    • volatile basically means that any writes to that field will be visible from other threads. So when you declare a field as volatile: private volatile SomeType field;, you are guaranteed that if the constructor writes to that field: field = new SomeType();, this assignment will be visible by other threads that subsequently try to read field.
    • final has quite similar semantics: you have the guarantee that if you have a final field: private final SomeType field; the write to that field (either in the declaration or in the constructor): field = new SomeType(); won't be reodered and will be visible by other threads if the object is properly published (i.e. no escape of this for example).
    • 显然,主要区别在于,如果该字段为final,则只能分配一次.

      Obviously, the main different is that if the field is final, you can only assign it once.

      例如,如果让this从构造函数中退出,则最终语义所提供的保证将消失:观察线程可能会看到具有其默认值的字段(对象为null).如果对象构造正确,就不会发生.

      If, for example, you let this escape from the constructor, the guarantee provided by the final semantics is gone: an observing thread might see the field with its default value (null for an Object). If the object is properly constructed this can't happen.

      人为的例子:

      class SomeClass{
          private final SomeType field;
      
          SomeClass() {
              new Thread(new Runnable() {
                  public void run() {
                      SomeType copy = field; //copy could be null
                      copy.doSomething(); //could throw NullPointerException
                  }
              }).start();
              field = new SomeType();
          }
      }
      

      这篇关于安全发布对象的最终vs易失性担保的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-22 19:19