views:

81

answers:

3

Is the snippet below "safe" for performing some initialization once in a multithreaded program?

I'm a bit worried that boxing/unboxing might cause some problem...

private static object initialized = false;

public static void Initialize()
{
  lock (initialized)
  {
    if ((bool)initialized == false)
    {
      DoInitialization();
      initialized = true;
    }
  }
}

Note that I can't just do the initialization from Main or some other single threaded context.

+3  A: 

You are right - that's not going to work because you are reassigning the object you are locking on.

You can do this with two seperate members - an object to lock on that is assigned only once, and then a boolean that you can read or assign to (after you have locked).

You may also want to consider if a singleton would be appropriate here.

Mark Byers
Or use a static constructor. Or the new `Lazy<T>` object.
Stephen Cleary
+1  A: 

A few options:

  1. lock on a once-assigned reference-type, as Mark has mentioned.
  2. Initialize on the static-constructor, which is guaranteed to only run once. Con: Hard to control when you want the initialization to occur.
  3. If possible, the Lazy class, which is thread-safe.

All 3 methods can also be used to create Singletons.

Ani
A: 

Try a double-checked locking.

    private static volatile bool initialized = false;
    private static object syncObject = new object();
    public static void Initialize() {
        if (!initialized) {
            lock (syncObject) {
                if (!initialized) {
                    DoInitialization();
                    initialized = true;
                }
            }
        }
    }
Jordão