以线程安全方式创建对象

Rol*_*all 5 java concurrency multithreading

直接来自这个网站,我遇到了关于创建对象线程安全性的以下描述.

警告:构造将在线程之间共享的对象时,要非常小心,对对象的引用不会过早"泄漏".例如,假设您要维护一个包含每个类实例的List调用实例.您可能想要将以下行添加到构造函数中:

instances.add(本);

但是其他线程可以在构造对象完成之前使用实例来访问对象.

是否有人能够用其他词语或其他更可抓住的例子来表达相同的概念?

提前致谢.

Ada*_*ion 5

  1. 让我们假设,您有这样的课程:

    class Sync {
        public Sync(List<Sync> list) {
            list.add(this);
            // switch
            // instance initialization code
        }
    
        public void bang() { }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 并且您有两个线程(线程 #1 和线程 #2),它们都引用了相同的List<Sync> list实例。

  3. 现在线程 #1 创建一个新Sync实例,并作为参数提供对list实例的引用:

    new Sync(list);
    
    Run Code Online (Sandbox Code Playgroud)
  4. 在构造函数中执行 line// switch时,Sync有一个上下文切换,现在线程 #2 正在工作。

  5. 线程 #2 执行这样的代码:

    for(Sync elem : list)
        elem.bang();
    
    Run Code Online (Sandbox Code Playgroud)
  6. 线程#2 调用bang()了第 3 点创建的实例,但是这个实例还没有准备好使用,因为这个实例的构造函数还没有完成。

所以,

  • 在调用构造函数并传递对几个线程之间共享的对象的引用时必须非常小心
  • 在实现构造函数时,您必须记住提供的实例可以在几个线程之间共享


til*_*ner -1

您只需确保即使一个线程尚未初始化该对象,也没有线程会访问它(并获得 NullpointerException)。

在这种情况下,它会发生在构造函数中(我想),但另一个线程可以在将其添加到列表和构造函数末尾之间访问该对象。