Home PC Games Linux Windows Database Network Programming Server Mobile  
           
  Home \ Programming \ Depth Java Singleton     - Examples of RAID levels and achieve Operational Details (Linux)

- Ubuntu Froxlor Server Administration panel installation (Server)

- hexdump Linux command (Linux)

- C ++ Supplements - Smart Pointers (Programming)

- C language macro definition #define Usage (Programming)

- Tsung first test installation (Linux)

- Shilpa Nair interview experience sharing RedHat Linux package management (Linux)

- BackTrack (BT3, BT4) Linux installation tutorial (Linux)

- Linux commands to access the cheat sheet (Linux)

- Create several practical points of high security PHP site (Linux)

- Static member variable modified (Programming)

- Openfire achieve load balancing cluster by Nginx (Server)

- Ubuntu install video conversion tool Selene (Linux)

- How to modify the Linux NIC eth1 to eth0 (Linux)

- Network security system (Network)

- Debian (Wheezy) were installed wxPython GUI development (Linux)

- Linux user login and IP restrictions (Linux)

- Bootable ISO image using GRUB (Linux)

- C ++ based foundation: the difference between C and C ++ (Programming)

- CentOS 6.4 Python 2.6 upgrade to 2.7 (Linux)

 
         
  Depth Java Singleton
     
  Add Date : 2018-11-21      
         
         
         
  In the 23 GoF design patterns, the Singleton pattern is a relatively simple one. However, sometimes the more simple things more prone to problems. Here Singleton design pattern in detail explore.

The so-called single-case model, simply, throughout the application to ensure that only instance of a class exists. Like the Java Web application, which is to provide a global variable, use a wide range, such as saving the global data, to achieve the overall operation.

1. The easiest way to implement

First of all, can think of the most simple implementation is to the class constructor written in private, so as to ensure that other classes can not instantiate this class, and then provide a static instance of the class and be able to return to the user. Thus, the user can use this reference to an instance of this class.

public class SingletonClass {

  private static final SingletonClass instance = new SingletonClass ();
    
  public static SingletonClass getInstance () {
    return instance;
  }
    
  private SingletonClass () {
    
  }
    
}

As example, if users want to use an external instance SingletonClass only through getInstance () method, and its constructor is private, thus ensuring only one object exists.

2. Performance Optimization --lazy loaded

The above code is simple, but there is a question - whether this class is being used, creates an instance object. If this process is very time-consuming to create, such as the need to connect 10000 database (exaggerated ... :-)), and this class also will not necessarily be used, then the creation process is useless. How to do it?

To solve this problem, we think the new solution:

public class SingletonClass {

  private static SingletonClass instance = null;
    
  public static SingletonClass getInstance () {
    if (instance == null) {
      instance = new SingletonClass ();
    }
    return instance;
  }
    
  private SingletonClass () {
    
  }
    
}

Code changes, there are two - first, the instance is initialized to null, until the first time used to create the object by determining whether the null. Because the process is not created at the statement, so that the final modifications must be removed.

Let's imagine this process. To use SingletonClass, call getInstance () method. The first time found instance is null, then create a new object, return out; the second time re-use, because this instance is static, it is not null, and it will not create an object, it directly return.

This process has become lazy loaded, that is, late loading - until time of use before loading.

3. Synchronization

The above code is very clear, very simple. However, as the famous phrase: "80% of the errors are caused by 20% due to code optimization." Single thread, this code is no problem, but if it is multi-threaded, trouble came. Let's analyze:

A thread you want to use SingletonClass, call getInstance () method. Because it is the first call, A found instance is null, so it starts to create an instance, at this time, CPU time slice switching occurs, the thread B begins execution, it uses SingletonClass, call getInstance () method, the same detection null-- instance is to be noted that this is finished after the detection switch a, that a did not have time to create an object - so B started. After B created, switch to A to continue, as it has been detected over, so A will not be detected again, it will create objects directly. Thus, the thread A and B each have a SingletonClass object - a single case of failure!

The solution is very simple, it is locked:

public class SingletonClass {

  private static SingletonClass instance = null;
    
  public synchronized static SingletonClass getInstance () {
    if (instance == null) {
      instance = new SingletonClass ();
    }
    return instance;
  }
    
  private SingletonClass () {
    
  }
    
}

To getInstance () plus synchronization lock, a thread must wait for another thread to create in order to use this method after completion, which ensures the uniqueness of the singleton.

4. Also the performance

The above code is very simple and very clear, however, the simple things are often less than ideal. This code is no doubt that there is a performance problem --synchronized modified sync block but slower than the average snippet on several times! If there are many times getInstance () call, that performance issues would have to consider it!

Let us analyze, what is the whole method must be locked, or only one in which a lock is enough? Why do we have to lock it? Analyze the reasons for that kind of situation lazy loaded. The reason is that operation detection null operation and create objects separated. If these two operations can be performed atomically, so a single case has been guaranteed. So, we start to modify the code:

public class SingletonClass {

  private static SingletonClass instance = null;
    
  public static SingletonClass getInstance () {
    synchronized (SingletonClass.class) {
      if (instance == null) {
        instance = new SingletonClass ();
      }
    }
    return instance;
  }
    
  private SingletonClass () {
    
  }
    
}

First, remove the getInstance () synchronous operation, and then loaded on the synchronization lock if statement. However, such modifications not have any effect: because each call to getInstance () when bound to synchronize, performance problem still exists. If ...... If we had to determine what is not null sync it to go?

public class SingletonClass {

  private static SingletonClass instance = null;

  public static SingletonClass getInstance () {
    if (instance == null) {
      synchronized (SingletonClass.class) {
        if (instance == null) {
          instance = new SingletonClass ();
        }
      }
    }
    return instance;
  }

  private SingletonClass () {

  }

}

Any question? First instance judgment is not for null, if null, lock initialization; if not null, return directly instance.

This is double-checked locking design and implementation of the Singleton pattern. So far, everything is perfect. We use a very clever way to achieve Singleton pattern.

5. Check the source

Here we begin to say compiler theory. The so-called compiler, the source code is "translated" into object code - mostly refers to machine code - process. For Java, it is not a local object code machine code, but the virtual machine code. Compiler theory there is a very important element is the compiler optimization. The so-called compiler optimization refers, without changing the semantics of the original case, by adjusting the sequence of statements, to make the program run faster. This process becomes reorder.

You know, JVM is a standard, not implementation. JVM and no provisions relating to the compiler optimized content, that is to say, free JVM implementations can be compiler optimizations.

Below to think about what steps to create a variable needs? Application is a piece of memory, call the constructor to initialize the operation, and the other is assigned a pointer to this memory. The two previous operations who who after that? JVM specification does not specify. Then there is such a case, JVM is to open up a piece of memory, then the pointer to this memory, and finally call the constructor to initialize.

Let us consider such a case: A thread creates an instance of SingletonClass the start, then thread B calls the getInstance () method, first determine whether the instance is null. As we mentioned above, the memory model, A has the instance pointing to that memory, but there was no call the constructor method, so B is detected instance is not null, then return directly to the instance - the question arises, though no instance it is null, but it has not been constructed, just as a house has given you the keys, but you can not live in, because it was not packed yet. At this time, if B in the A structure is completed before the instance is to use this instance, the program will be wrong!

So, we think the following code:

public class SingletonClass {

  private static SingletonClass instance = null;

  public static SingletonClass getInstance () {
    if (instance == null) {
      SingletonClass sc;
      synchronized (SingletonClass.class) {
        sc = instance;
        if (sc == null) {
          synchronized (SingletonClass.class) {
            if (sc == null) {
              sc = new SingletonClass ();
            }
          }
          instance = sc;
        }
      }
    }
    return instance;
  }

  private SingletonClass () {

  }
    
}

We created in the first sync block inside a temporary variable, then use this temporary variable to create objects, and in the last instance variable pointer temporary memory space. Write this code is based on the idea that the code synchronized will play a role in shielding, inside the block synchronization code and no code outside contact. Therefore, the external sync blocks inside the temporary variable sc operation does not affect instance, so the external class instance = sc; prior to detection instance, when the result instance is still null.

However, this idea is completely wrong! Sync blocks release guarantees before - that is synchronized block inside - operations must be done, but does not guarantee the operation of sync block after not because of compiler optimization to be exchanged before the end of the sync block. Therefore, the compiler can put instance = sc; sentence moved inside the internal synchronization block execution. Thus, the program is wrong!

6. Solutions

Having said that, there is no way to do a single case in Java to achieve it? actually not!

After JDK 5, Java uses the new memory model. volatile keyword with a clear semantics - before JDK1.5, volatile is a keyword, but it does not clearly defined its purpose - to be volatile write variables can not be modified and adjusted before reading and writing the code, and can not read variables after the reading and writing code tuning! Therefore, if we simply put instance plus the volatile keyword on it.

public class SingletonClass {

  private volatile static SingletonClass instance = null;

  public static SingletonClass getInstance () {
    if (instance == null) {
      synchronized (SingletonClass.class) {
        if (instance == null) {
          instance = new SingletonClass ();
        }
      }
    }
    return instance;
  }

  private SingletonClass () {

  }
    
}

However, this is only after JDK1.5 Java solution before that version? In fact, there is another kind of solution, and the impact will not be Java version:

public class SingletonClass {
    
  private static class SingletonClassInstance {
    private static final SingletonClass instance = new SingletonClass ();
  }

  public static SingletonClass getInstance () {
    return SingletonClassInstance.instance;
  }

  private SingletonClass () {

  }
    
}

Singleton pattern implementation code in this version, we use a Java static inner classes. This technique is clearly stated in the JVM, it is not any ambiguity remains. In this code, because SingletonClass no static properties, and therefore will not be initialized. Until the call getInstance () when will first load SingletonClassInstance class that has a static SingletonClass instance, so you need to call the constructor SingletonClass, and getInstance () will return this internal class instance to the user. Since this instance is static, so many times and not constructed.

Since SingletonClassInstance is private static inner class, so it will not be aware of other types of the same, static semantics requirements do not have multiple instances exist. And, JSL specification defined class structure must be atomic, uncomplicated, and therefore do not need to add sync blocks. Also, since the structure is concurrent, so getInstance () does not need to add synchronization.

At this point, we have a complete understanding of the Singleton pattern in the Java language, when proposed two solutions. Personally I prefer the second, and Effiective Java also recommended this approach.
     
         
         
         
  More:      
 
- Linux installation is larger than 2TB (UEFI interface) hard disk solution (Linux)
- Questions about Linux compiler u-boot (Programming)
- The best tools and techniques to find data on a Unix system (Linux)
- Linux kernel IPv6 protocol closed manner (Linux)
- Windows Remote Desktop Management CentOS 6.4 (Linux)
- LVM mirrored logical volume to achieve (Linux)
- Macro Analysis Performance: PHP Performance Analysis and Experiment (Programming)
- Linux system security check method (Linux)
- Git Rebase Tutorial: Using Git Rebase turn back the clock (Linux)
- SVN hook code set to synchronize Web directory (Server)
- Use Bosh deploy CloudFoundry problems encountered on OpenStack (Server)
- Linux netstat command to get started (Linux)
- Bubble Sort Algorithms (Programming)
- CentOS Linux firewall configuration and Close (Linux)
- Flask deploy applications using Nginx on Ubuntu (Server)
- Upload the project to GitHub, synchronous remote repository Github (Linux)
- Mongo-connector integrated MongoD to achieve incremental Solr index (Server)
- Linux host dual LAN transceiver package ARP problem (Linux)
- Node.js Getting the basics: Helloworld! (Linux)
- Spark source code compiler package (Linux)
     
           
     
  CopyRight 2002-2022 newfreesoft.com, All Rights Reserved.