开发者

lazy initialization of singletons

开发者 https://www.devze.com 2022-12-11 21:00 出处:网络
While reading Jon Skeet\'s article on singletons in C# I started wondering why we need l开发者_StackOverflow中文版azy initialization in a first place. It seems like the fourth approach from the articl

While reading Jon Skeet's article on singletons in C# I started wondering why we need l开发者_StackOverflow中文版azy initialization in a first place. It seems like the fourth approach from the article should be sufficient, here it is for reference purposes:

public sealed class Singleton
{
    static readonly Singleton instance=new Singleton();

    // Explicit static constructor to tell C# compiler
    // not to mark type as beforefieldinit
    static Singleton()
    {
    }

    Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            return instance;
        }
    }
}

In the rare circumstances, where you have other static methods on a singleton, lazy initialization may have benefits, but this is not a good design.

So can people enlighten me why lazy initialization is such a hot thing?


In those scenarios where whatever it is you are initializing might not be needed at all, and is expensive to initialize, (in terms of CPU cycles or resources), then implementing a lazy initializor saves that cost in those cases where the object is not required.

If the object will always be required, or is relatively cheap to initialize, then there is no added benefit from a lazy initializer.

In any event, implementing a lazy initializer improperly can make a singleton non-thread-safe, so if you need this pattern, be careful to do it correctly. Jon's article has a pattern, (I think it's the last one), that addresses this issue.


You don't need lazy initialization on a singleton, if the only reason you're going to use that type is to reference the instance.

If, however, you reference any other property or method on the type, or the type itself, you will initialize the singleton.

Granted, good design would leave one task for one type, so this shouldn't be a problem. If you make your singleton class to "complex", however, lazy initialization can help keep you from having consequences due to initializing too soon.


I'm not sure that this applies to C# as well, but I'll answer for C++:

One of the ideas behind Singletons is that the order of initialization of static objects is undefined. So if you have a static class that tries to use another static class, you might be in trouble.

A concrete example: Let's say I have a Log class, which I decided to implement as a Singleton. Let's also assume I have a method called LoadDB, which for whatever reason, is a static called at the start of the program. Assuming LoadDB decides it needs to log something, it will call the Singleton. But since the order of static initialization is undefined, it might be doing something that's an error.

A Singleton fixes this, since once you call GetInstance(), no matter where you are in the initialization process, the object is guaranteed to exist.

Again, I don't know if this is relevant, but at least that's the history of it (as far as I remember).


From Java DI perspective, lazy initialization is good, there are always (say, spring) beans in another API that you might not want to use, for example, an eagerly loaded singleton cache (something that is shared with everyone using the cache) might not be needed for you although it may be referred as a dependency in your same code. Whats the point in loading the singleton wasting resources?

The lazy initialization implementation choice is tricky, in spring, would you choose lazy-init="true" (spring eagerly instantiates singletons), an init-method/destroy-method, @PostConstruct, InitializingBean - afterPropertiesSet() method or return same spring instance in a getInstance() method?

The choice is a tradeoff of testability over reusability outside the spring container.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号