Ensuring initialization methods complete before member variable is accessed

无人久伴 提交于 2019-12-12 02:52:13

问题


Is there a way of ensure that a set of methods operating on a volatile static member variable via one thread will be done and over with before other threads access this member variable? I am trying something like this, but I am not sure if it would work.

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

回答1:


You need to delay the assignment of mo until after all the methods are called (i.e. use a local variable and then assign mo as the last step).

Note, you are essentially implementing double checked locking (although using volatile makes it work "correctly"). you need to check mo for null again within the synchronized block.

also, there are some other (somewhat better) patterns for this like using the class initialization pattern for managing the synchronization. Pretty much every pattern imaginable is detailed here http://en.wikipedia.org/wiki/Singleton_pattern




回答2:


You're looking for the singleton pattern, using the double-checked locking idiom:

private static volatile MyObj obj = null;

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

Note that the field is private, and accessed vie a getObj() method (and only through this method). If a field is public, any thread can access it whenever it wants to: you can't synchronize the access to a field without encapsulating its accesses behind methods.

There are easier ways to have this guarantee, but if you want lazy initialization, all of them, AFAIK, will require calling a method.




回答3:


You could set up a getter and have some flags which it checks to ensure that whatever methods are executed. The getter can either wait for the execution to finish to launch the required methods itself.



来源:https://stackoverflow.com/questions/18357959/ensuring-initialization-methods-complete-before-member-variable-is-accessed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!