Three single-instance patterns of Java Design patterns (Singleton)

Source: Internet
Author: User

A singleton object (Singleton) is a common design pattern. In Java applications, singleton objects guarantee that only one instance of the object exists in a JVM. There are several benefits to this model:

1, some classes are created more frequently, for some large objects, this is a lot of overhead.

2, eliminate the new operator, reduce the use of system memory frequency, reduce the GC pressure.

3, some classes such as the exchange's core trading engine, control the trading process, if the class can create multiple words, the system is completely chaotic. (for example, an army has multiple commanders at the same time command, it will certainly mess), so only using a singleton mode can ensure that the core trading server independently control the entire process.

First, let's write a simple singleton class:

[Java]View Plaincopy
  1. public class Singleton {
  2. /* Holds private static instances, prevents references, and assigns null here to enable lazy loading */
  3. private static Singleton instance = NULL;
  4. /* Private construction method to prevent instantiation of */
  5. Private Singleton () {
  6. }
  7. /* Static Engineering method, create instance */
  8. public static Singleton getinstance () {
  9. if (instance = = null) {
  10. Instance = new Singleton ();
  11. }
  12. return instance;
  13. }
  14. /* If the object is used for serialization, you can ensure that the object remains consistent before and after serialization.
  15. Public Object Readresolve () {
  16. return instance;
  17. }
  18. }


This class can meet the basic requirements, but, like this no thread-safe class, if we put it into multi-threaded environment, there will be problems, how to solve? We will first think of the GetInstance method plus the Synchronized keyword, as follows:

[Java]View Plaincopy
    1. public static synchronized Singleton getinstance () {
    2. if (instance = = null) {
    3. Instance = new Singleton ();
    4. }
    5. return instance;
    6. }

However, the Synchronized keyword lock is the object, such usage, will be degraded in performance, because each call to getinstance (), the object must be locked, in fact, only when the first time the object is created to lock, and then do not need, so, This place needs to be improved. Let's change to the following:

[Java]View Plaincopy
  1. public static Singleton getinstance () {
  2. if (instance = = null) {
  3. Synchronized (instance) {
  4. if (instance = = null) {
  5. Instance = new Singleton ();
  6. }
  7. }
  8. }
  9. return instance;
  10. }

Seems to solve the problem mentioned earlier, the Synchronized keyword is added to the internal, that is, when the call is not required to lock, only when the instance is null, and create the object only need to lock, performance has a certain elevation. However, there may be problems with this, see the following: creating objects and assigning operations in Java directives is done separately, that is, instance = new Singleton (); The statement is executed in two steps. However, the JVM does not guarantee the sequencing of the two operations, which means that it is possible for the JVM to allocate space for the new singleton instance and then assign the value directly to the instance member before initializing the singleton instance. This can be a mistake, we take a, b two threads as an example:

A>a, B Threads Enter the first if judgment at the same time

B>a first enters the synchronized block, because instance is null, so it executes instance = new Singleton ();

C> because of the optimization mechanism inside the JVM, the JVM first draws some blank memory allocated to the singleton instance and assigns it to the instance member (note that the JVM does not start initializing the instance at this time), and a leaves the synchronized block.

D>b enters the synchronized block because instance is not NULL at this time, so it immediately leaves the synchronized block and returns the result to the program that called the method.

E> this time the B thread intends to use the singleton instance, but finds that it was not initialized, and the error occurred.

So the program is still possible error, in fact, the program is very complex in the process of operation, from this point we can see, especially in the writing multi-threaded environment of the program is more difficult, challenging. We have further optimized the program:

[Java]View Plaincopy
    1. private Static Class singletonfactory{
    2. private static Singleton instance = new Singleton ();
    3. }
    4. public static Singleton getinstance () {
    5. return singletonfactory.instance;
    6. }

The reality is that the singleton pattern uses an internal class to maintain the implementation of the Singleton, and the mechanism inside the JVM guarantees that when a class is loaded, the loading process of the class is thread-mutually exclusive. So when we first call getinstance, the JVM can help us ensure that instance is created only once and that the memory assigned to instance is initialized so we don't have to worry about the problem. At the same time, the method only uses the mutex mechanism when the first call is made, which solves the low performance problem. This allows us to briefly summarize a perfect singleton pattern:

[Java]View Plaincopy
  1. public class Singleton {
  2. /* Private construction method to prevent instantiation of */
  3. Private Singleton () {
  4. }
  5. /* Use an inner class here to maintain the singleton */
  6. private Static Class Singletonfactory {
  7. private static Singleton instance = new Singleton ();
  8. }
  9. /* Get instance */
  10. public static Singleton getinstance () {
  11. return singletonfactory.instance;
  12. }
  13. /* If the object is used for serialization, you can ensure that the object remains consistent before and after serialization.
  14. Public Object Readresolve () {
  15. return getinstance ();
  16. }
  17. }

In fact, it is perfect, not necessarily, if an exception is thrown in the constructor, the instance will never be created and will be faulted. So, the very perfect thing is not, we can only according to the actual situation, choose the most suitable for their own application of the implementation of the scenario. Others do this: because we only need to synchronize when creating the class, it is also possible to create the Synchronized keyword separately, as long as the creation and getinstance () are created separately:

[Java]View Plaincopy
  1. public class Singletontest {
  2. private static Singletontest instance = NULL;
  3. Private Singletontest () {
  4. }
  5. private static synchronized void Syncinit () {
  6. if (instance = = null) {
  7. Instance = new Singletontest ();
  8. }
  9. }
  10. public static Singletontest getinstance () {
  11. if (instance = = null) {
  12. Syncinit ();
  13. }
  14. return instance;
  15. }
  16. }

With performance in mind, the entire program only needs to create one instance at a time, so performance has no effect.

Supplement: Use Shadow instance to synchronize updates for properties of Singleton objects

[Java]View Plaincopy
  1. public class Singletontest {
  2. private static Singletontest instance = NULL;
  3. Private Vector properties = null;
  4. Public Vector getProperties () {
  5. return properties;
  6. }
  7. Private Singletontest () {
  8. }
  9. private static synchronized void Syncinit () {
  10. if (instance = = null) {
  11. Instance = new Singletontest ();
  12. }
  13. }
  14. public static Singletontest getinstance () {
  15. if (instance = = null) {
  16. Syncinit ();
  17. }
  18. return instance;
  19. }
  20. public void Updateproperties () {
  21. Singletontest shadow = new Singletontest ();
  22. Properties = Shadow.getproperties ();
  23. }
  24. }

Learning through a singleton pattern tells us:

1, the single-case model is simple to understand, but the specific implementation is still a certain degree of difficulty.

2, synchronized keyword lock is the object, in use, it must be used in the appropriate place (note the need to use the lock object and process, may not be the whole object and the whole process need to lock).

Here, the singleton mode has been basically finished, at the end, I suddenly think of another problem, is the use of static methods of the class, to achieve the effect of a single-case model, is also feasible, here are the differences?

First, a static class cannot implement an interface. (It's possible from a class point of view, but that destroys the static.) Because static modifiers are not allowed in the interface, they are non-static even if implemented

Second, a singleton can be delayed initialized, and static classes are typically initialized in the first load. Delay loading is because some classes are large, so lazy loading can help improve performance.

Again, a singleton class can be inherited, and his method can be overwritten. However, static class internal methods are static and cannot be overwritten.

Finally, the Singleton class is more flexible, after all, from the implementation is just a common Java class, as long as the basic needs of the singleton, you can do in the arbitrary implementation of some other functions, but static class does not. From the above summary, the basic can see the difference between the two, but, on the other hand, we finally realized that the singleton pattern, the interior is a static class to achieve, so, the two have a great correlation, but we consider the level of the problem is different. The combination of two ideas to create a perfect solution, just like HashMap using array + linked list to achieve the same, in fact, many things in life are so, alone with different methods to deal with problems, there are always advantages and disadvantages, the most perfect way is to combine the advantages of each method, to best solve the problem!

Three single-instance patterns of Java Design patterns (Singleton)

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.