简体   繁体   中英

Name for this pattern? (Answer: lazy initialization with double-checked locking)

Consider the following code:

public class Foo
{
    private static object _lock = new object();

    public void NameDoesNotMatter()
    {
        if( SomeDataDoesNotExist() )
        {
            lock(_lock)
            {
                if( SomeDataDoesNotExist() )
                {
                    CreateSomeData();
                }
                else
                {
                    // someone else also noticed the lack of data.  We
                    // both contended for the lock.  The other guy won
                    // and created the data, so we no longer need to.
                    // But once he got out of the lock, we got in.
                    // There's nothing left to do.
                }
            }
        }
    }

    private bool SomeDataDoesNotExist()
    {
        // Note - this method must be thread-safe.
        throw new NotImplementedException();
    }

    private bool CreateSomeData()
    {
        // Note - This shouldn't need to be thread-safe
        throw new NotImplementedException();
    }
}

First, there are some assumptions I need to state:

  1. There is a good reason I couldn't just do this once an app startup. Maybe the data wasn't available yet, etc.

  2. Foo may be instantiated and used concurrently from two or more threads. I want one of them to end up creating some data (but not both of them) then I'll allow both to access that same data (ignore thread safety of accessing the data)

  3. The cost to SomeDataDoesNotExist() is not huge.

Now, this doesn't necessarily have to be confined to some data creation situation, but this was an example I could think of.

The part that I'm especially interested in identifying as a pattern is the check -> lock -> check. I've had to explain this pattern to developers on a few occasions who didn't get the algorithm at first glance but could then appreciate it.

Anyway, other people must do similarly. Is this a standardized pattern? What's it called?

Though I can see how you might think this looks like double-checked locking, what it actually looks like is dangerously broken and incorrect double-checked locking . Without an actual implementation of SomeDataDoesNotExist and CreateSomeData to critique we have no guarantee whatsoever that this thing is actually threadsafe on every processor.

For an example of an analysis of how double-checked locking can go wrong, check out this broken and incorrect version of double-checked locking:

C# manual lock/unlock

My advice: don't use any low-lock technique without a compelling reason and a code review from an expert on the memory model; you'll probably get it wrong. Most people do.

In particular, don't use double-checked locking unless you can describe exactly what memory access reorderings the processors can do on your behalf and provide a convincing argument that your solution is correct given any possible memory access reordering . The moment you step away even slightly from a known-to-be-correct implementation, you need to start the analysis over from scratch. You can't assume that just because one implementation of double-checked locking is correct, that they all are; almost none of them are correct.

带有双重检查锁定的延迟初始化?

The part that I'm especially interested in identifying as a pattern is the check -> lock -> check.

That is called double-checked locking .

Beware that in older Java versions (before Java 5) it is not safe because of how Java's memory model was defined. In Java 5 and newer changes were made to the specification of Java's memory model so that it is now safe.

The only name that comes to mind for this kind of is "Faulting". This name is used in iOS Core-Data framework to similar effect.

Basically, your method NameDoesNotMatter is a fault , and whenever someone invokes it, it results in the object to get populated or initialized.

See http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdFaultingUniquing.html for more details on how this design pattern is used.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM