Summary and expansion of several single-instance implementations

Source: Internet
Author: User

This article is a summary of the study of Uncle Tom and does not allow the interviewer to ask you a single example (and six ways to block the interviewer's mouth. ------ Some people are outside the world. The blog Park is a paradise for. Net technicians!

The purpose of writing a text is not to say how important a single example is. In fact, it is more recommended that the bloggers in the blog park view the interviewer's questions from another perspective during the interview.Proactive attackThat is to say, when a person asks you a question, never think about the surface of the question. There may also be many traps (because the interviewer usually does not have too much time to interview, generally, the first appointment is 60-90 minutes, so it is not likely to ask too many questions. You can only ask a few questions, and then wait for a variety of questions based on these questions), so when you answer questions, try to avoid these traps. For example, we often talk about locking and threads in a single example. If you are not familiar with multithreading, then we can take the initiative to say the implementation of double locks, and then turn back to the topic and say: "In fact, there are a lot of things we need to examine in a single example, such as private constructor, static constructor, and static fields, what is the difference between readonly and const? "In fact, after so many times, the interviewer will not hold on to the Singleton, maybe it's just a symbolic question about the differences between constructors, because at this time, he knows that you basically understand the relevant content. Of course, if you want the interviewer to ask you another question for half an hour, you can take the interviewer's nose. However, I think this is generally not possible.

To avoid misunderstanding, add: The purpose of this question is not just for Singleton, but to evaluate basic knowledge, such as static constructors, private constructors, locks, and delayed object creation, the difference between readonly and const is not simply about the hero in singleton. The reason why the interviewer thinks it feels good is mainly to give one or two Singleton examples, and then he feels that he has passed the interview, in fact, the interviewer did not notice the real content to be examined.

The following is a list of different Singleton versions obtained during the interview. For more information, see:

Version 1: recruiter

using System;
public sealed class Singleton
{
private static Singleton instance;
private Singleton() { }
public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}

Private constructor:If a class contains a private constructor, the class cannot be initialized using this constructor. Generally, it can only call its static method. Singleton mode is commonly used.
If a class contains both private constructor and public constructor, the class can be initialized, but only in the form of public constructor. Therefore, it is not rigorous to say that classes contain private constructors and classes cannot be initialized.

The main problem with this version isThread security issuesWhen two requests use this class at the same time, an instance can be created at the same time. Although no exception error occurs, but at least we are not talking about ensuring only one instance.

Version 2

Public sealed class Singleton
{
// Declare the singleton on the static private field
Private Static readonly Singleton instance = new Singleton ();
// Private constructor to ensure that you cannot create new instances externally
Private Singleton (){}
// Return static fields for read-only attributes
Public static Singleton instance
{
Get
{
Return instance;
}
}
}

We all know that const and static readonly are indeed very similar: access by class name rather than Object Name, read-only in the program, and so on. In most cases, they can be mixed. The essential difference between the two is that the const value is determined during compilation, so it can only be specified through a constant expression during declaration. Static readonly calculates its value during running, so it can be assigned a value through a static constructor.

It is good to mark the class as sealed, which can prevent integration and then be instantiated in the subclass;

It is a good method to create an instance when the class is called for the first time through the new form in the static private field, but note that, C # does not guarantee the instance creation time, because the C # standard only marks the static field in Il as beforefieldinit, that is, the static field may be created when it is used for the first time, or you may not have used it. It also helps you create it, that is, the cycle is earlier. We cannot determine what the instance was created.
Version 3

Public sealed class Singleton
{
// Still the static automatic hold instance
Private Static volatile Singleton instance = NULL;
// Lock Object, used for thread security
Private Static object syncroot = new object ();
Private Singleton (){}
Public static Singleton instance
{
Get
{
If (instance = NULL)
{
Lock (syncroot)
{
If (instance = NULL)
Instance = new Singleton ();
}
}
Return instance;
}
}
}

Using volatile for modification is a good note. It ensures that the instance is assigned a value before being accessed. This method is generally used to implement Singleton.

Version 4

Public class Singleton
{
// Because the static constructor is declared below, the new Singleton () statement will not be executed before the class is accessed for the first time.
Private Static readonly Singleton _ instance = new Singleton ();
Public static Singleton instance
{
Get {return _ instance ;}
}
Private Singleton (){}
// Declare a static constructor to delete the beforefieldinit mark in Il.
// To ensure that the static state is automatically initialized before use
Static Singleton (){}
}

This method is actually very good, because it does ensure that it is a single example of delayed initialization (by adding a static constructor), but there is nothing in this static constructor, so sometimes it may cause misunderstanding, especially when code review or code optimization, unfamiliar people may directly help you delete this code, and then return to version 2, so pay attention to it, but if you have code to execute at this time, that would be nice.
Version 5

public sealed class Singleton 
{
private Singleton() { }
public static Singleton Instance { get { return Nested._instance; } }
private class Nested
{
static Nested() { }
internal static readonly Singleton _instance = new Singleton();
}
}

This is actually a variant of Version 4.
Version 6

Public class Singleton
{
// Use Lambda because the constructor is private
Private Static readonly lazy <Singleton> _ instance = new lazy <Singleton> () => New Singleton ());
// New lazy <Singleton> () => New Singleton (), lazythreadsafetymode. executionandpublication );
Private Singleton (){}
Public static Singleton instance
{
Get {return _ instance. value ;}
}
}

In fact, the default constructor of lazy can only call the Public constructor of the incoming generic type T, but in this example, because the code is inside our Singleton, therefore, it is okay to call a private constructor. You may have another doubt that this method can achieve thread security in addition to lazy initialization? Let's take a look at the code that has been commented out on the previous layer. There is an additional lazythreadsafetymode. the executionandpublication parameter is used to set thread security. However, because the default setting of lazy <t> is thread security, it is also effective to disable it.

Therefore, during the interview, if I can explain the implementation principles of the above six versions for two minutes, I guess the interviewer will not hold on to the singleton in general, in addition, if you basically have no problem with what you say, at this time, the interviewer usually has a crush on you, at least I am like this, at least you have already reflected some basic knowledge of C # In this Singleton question, isn't it?

Extension

Of course, if you cannot answer so many questions at this time, I will not be so entangled in this question, so that the intense atmosphere will not affect subsequent discussions, normally, I will switch to another topic in time (for example, the strongest skill on your resume to restore your confidence). If your questions and answers are good, in fact, I still want to ask a little more, just a little bit: how to implement a wildcard version Singleton?

This is a bonus. Someone previously gave the following code:

public class Singleton<T> where T : new() 
{
private static readonly Lazy<T> _instance = new Lazy<T>(() => new T());
public static T Instance
{
get { return _instance.Value; }
}
}

I have considered this version when I asked myself this question, but in fact it is problematic, that is, the new T (). In this case, T has a public constructor by default, right? That is to say, T may have multiple instances, because it does not meet our prerequisites: Your class cannot be instantiated externally.

Let's post a piece of code provided by foreigners:

public abstract class Singleton 
{
private static readonly Lazy<T> _instance = new Lazy<T>
( () =>
{ var ctors = typeof(T).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
if (ctors.Count() != 1)
throw new InvalidOperationException(String.Format("Type {0} must have exactly one constructor.", typeof(T)));
var ctor = ctors.SingleOrDefault(c => c.GetParameters().Count() == 0 && c.IsPrivate);
if (ctor == null)
throw new InvalidOperationException(String.Format("The constructor for {0} must be private and take no parameters.", typeof(T)));
return (T)ctor.Invoke(null);
}
);
public static T Instance
{
get { return _instance.Value; }
}
}

From top to bottom, let's see how it is implemented:

  1. Declare abstract classes so that they cannot be used directly. You must inherit the class before using them.
  2. Using lazy <t> As _ instance, T is the inheritance class for implementing a single instance.
  3. The constructor of the lazy class has a parameter (func type), which is the same as our version 6.
  4. According to Microsoft documents and Singleton features, the constructor of Singleton classes must be private, so corresponding verification should be added here
  5. Once the verification is passed, the private no-argument constructor invoke does not have to worry about its efficiency, because it only runs once!
  6. The instance property returns a unique T instance.

Let's implement a singleton class:

class MySingleton : Singleton<MySingleton> 
{
int _counter;
public int Counter
{
get { return _counter; }
}
private MySingleton()
{
_counter = 0;
}
public void IncrementCounter()
{
++_counter;
}
}

This example is normal, but there is still a problem in parallel computing, because the above generic version of the Code uses lazy <t> to ensure that we are thread safe when creating a singleton instance, but it does not mean that the singleton itself is thread safe, let's take an example:

static void Main(string[] args)        
{
Parallel.For(0, 100, i =>{
for (int j = 0; j < 1000; ++j) MySingleton.Instance.IncrementCounter();
});
Console.WriteLine("Counter={0}.", MySingleton.Instance.Counter);
Console.ReadLine();
}

The counter result is usually less than 100000, because the code of the incrementcounter method in a single instance is not protected by thread security itself, so if we want to get an accurate 100000 value, we need to modify the incrementcounter method code of mysingleton:

public void IncrementCounter()        
{
Interlocked.Increment(ref _counter);
}

In this way, the results will be perfect, and the problem about Singleton is almost here. Let's summarize the advantages and disadvantages of Singleton.

Summary

Advantages of singleton:

1. Ensure that all objects access the same instance

2. Because classes are instantiated under the control of their own classes, they have corresponding scalability.
Disadvantages of singleton:

1. Additional system overhead, because every time you use a class instance, you must check whether the instance exists. This can be solved through a static instance.

2. The object cannot be destroyed. The single-instance mode determines that only the object instance can be destroyed by itself, but we generally do not do this.

[Recommendation: Uncle Note: Workshop ~ Wish you all a happy and progressive life!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.