Before I often saw a variety of singleton mode of interview sharing, but everyone will share a little different, after their own implementation, I found that although the singleton mode is not difficult, but the interviewer always contains some routines in it.

First, what is a singleton

To make the system run with only one instance of the object. The principle is simple, so here are some common questions that interviewers ask.

Is the singleton pattern understood? Writing a

To the code

public class Singleton {

    private static Singleton uniqueInstance;

    private Singleton(a) {}public static Singleton getUniqueInstance(a) {
        if(uniqueInstance ! =null) {
            return uniqueInstance;
        }
        uniqueInstance = new Singleton();
        returnuniqueInstance; }}Copy the code
public class Singleton {

    private static Singleton uniqueInstance = new Singleton();

    private Singleton(a) {}public static Singleton getUniqueInstance(a) {
        returnuniqueInstance; }}Copy the code

I believe that if not prepared before, the first reaction written affirmation is one of the two, but this writing is the most basic, and write so have to make a clear distinction between the difference between the two, the first is the so-called slug singleton pattern, why do you say that, because when loading the corresponding won’t go to initialize instance, Instead, it waits until getUniqueInstance() is called, and the second is the hungry singleton pattern, which is instantiated as soon as it comes in, but because it’s static, it only instantiates once, and then returns when the method is called. But I would say that if you were to write the singleton and write it that far, the interviewer would probably start asking other questions.

How can your singleton be thread safe?

The first reaction is to lock, use the synchronize keyword, and then code. The rest of this tutorial adds code to the first slacker pattern.

public class Singleton {

    private static Singleton uniqueInstance;

    private Singleton(a) {}public static Singleton getUniqueInstance(a) {
        synchronized (Singleton.class) {
            if (uniqueInstance == null) {
                uniqueInstance = newSingleton(); }}returnuniqueInstance; }}Copy the code

How to achieve thread safety through double checklock?

First do not be afraid, split is double check lock, see the code

public class Singleton {

    private static volatile Singleton uniqueInstance;

    private Singleton(a) {}public static Singleton getUniqueInstance(a) {
        if (uniqueInstance == null) {
            synchronized (Singleton.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = newSingleton(); }}}returnuniqueInstance; }}Copy the code

Does uniqueInstance have to be volatile?

For those who have noticed that the volatile keyword is used in this code, let me explain. The volatile modifier is necessary because uniqueInstance = new Singleton(); The final implementation of the code is in three steps,

  1. First allocate memory space for uniqueInstance
  2. instantiation
  3. Assigning a uniqueInstance to an allocated memory address is fine in single-threaded cases, but in multi-threaded threads, the JVM may rearrange instructions to point to the instantiated address as soon as the memory space is allocated, but the second step has not yet taken place. That is, without instantiation, a null pointer exception occurs. The volatile keyword ensures that JVM implementations are sequential.

Finally, I share a singleton pattern that implements a simulated Spring container

public class ContainerSingleton {

    private static final Logger LOGGER = LoggerFactory.getLogger(ContainerSingleton.class);

    private ContainerSingleton(a) {}private static Map<Object, Object> ioc = new ConcurrentHashMap<>();

    public static Object getUniqueInstance(String className) {
        synchronized (ioc) {
            if(! ioc.containsKey(className)) { Object obj =null;
                try {
                    obj = Class.forName(className).newInstance();
                    ioc.put(className, obj);
                } catch(Exception e) { LOGGER.error(e.getMessage(), e); }}}returnioc.get(className); }}Copy the code

conclusion

There are many types of singleton patterns, and you need to understand the design model and then understand it.