确保在访问成员变量之前完成初始化方法

时间:2013-08-21 12:52:52

标签: java static synchronization locking

是否有办法确保通过一个线程易变的静态成员变量进行操作的一组方法将在其他线程之前完成访问此成员变量?我正在尝试这样的事情,但我不确定它是否会奏效。

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();
      }
    }
  }
}

3 个答案:

答案 0 :(得分:1)

在调用所有方法之后,您需要延迟mo的分配,直到(即使用局部变量,然后将mo指定为 last < / em> step)。

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

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

答案 1 :(得分: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都需要调用方法。

答案 2 :(得分:0)

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