0

有没有办法确保在其他线程访问该成员变量之前,通过一个线程对volatile 静态成员变量进行操作的一组方法将完成并结束?我正在尝试这样的事情,但我不确定它是否会起作用。

public class MyClass
{
  private static final Object lock = new Object();
  public static volatile MyObj mo; //assume null will be checked before access

  public static void initialize()
  {
    if (mo == null)
    {
      synchronized(lock)
      {
        mo = new MyObj();
        mo.doInit();
        mo.doMoreInit();
      }
    }
  }
}
4

3 回答 3

1

您需要延迟分配,mo直到调用所有方法之后mo(即使用局部变量,然后分配作为最后一步)。

请注意,您实际上是在实现双重检查锁定(尽管使用 volatile 使其“正确”工作)。您需要同步块中 mo再次检查 null 。

此外,还有一些其他(更好的)模式,比如使用类初始化模式来管理同步。几乎所有可以想象的模式都在这里详细介绍http://en.wikipedia.org/wiki/Singleton_pattern

于 2013-08-21T12:56:15.787 回答
1

您正在寻找单例模式,使用双重检查锁定习语:

private static volatile MyObj obj = null;

public static MyObj getObj() {
    if (obj == null) {
        synchronized (MyClass.class) {
            if (obj == null) {
                obj = new MyObj();
            }
        }
    }
    return obj;
}

请注意,该字段是私有的,并且可以通过getObj()方法访问(并且只能通过此方法)。如果一个字段是公共的,那么任何线程都可以随时访问它:如果不将其访问封装在方法后面,就无法同步对字段的访问。

有更简单的方法可以获得这种保证,但如果你想要延迟初始化,所有这些,AFAIK,都需要调用一个方法。

于 2013-08-21T13:00:01.953 回答
0

您可以设置一个 getter 并有一些标志,它会检查以确保执行任何方法。getter 可以等待执行完成以启动所需的方法本身。

于 2013-08-21T12:55:01.463 回答