Single-piece Mode

Source: Internet
Author: User

Some people say that the single-piece mode is the simplest mode, because it only has one class, but it still has some worth noting. For example, when concurrency occurs, a single piece may not be a single piece anymore.

First, let's explain why we need to use the single-piece mode. When we use these objects, such as thread pools, caches, registries, and log objects, we can only have one instance of these objects, otherwise, many problems may occur, so we need to make it a single piece.

You may say that you can use conventions between programmers or global variables, such as static variables in Java. Yes, but a disadvantage of global variables is that they must be created at the beginning of the program. If this object is very resource-consuming and the program has never used it, isn't that a waste? The single-piece mode overcomes this shortcoming.

How can we implement this single-piece mode? First, this class can only be instantiated once, which means that its constructor cannot be made public. If so, how can I instantiate it? In fact, we can do this: (this is a classic single-piece Mode)

Public class Singleton {Private Static Singleton uniqueinstance; // use a static variable to record the unique instance of the singleton class // other useful instance variables here private Singleton () {} // only the user can call the constructor public static Singleton getinstance () {// breakpoint 1 (used for text parsing below) if (uniqueinstance = NULL) {// breakpoint 2 uniqueinstance = new Singleton (); // It is created only when uniqueinstance does not exist} return uniqueinstance;} // other useful methods here}

If you think this is perfect, it would be naive. It is indeed perfect to run in a single thread, but if there are many concurrent threads, the single piece may not be a single piece.

For example, there are two threads a and B. When the single-piece class is not instantiated, both the and B threads are executed to the breakpoint 1, because the single-piece class is not instantiated yet, therefore, you can execute breakpoint 2. When a first instantiates a single-piece class, although it has already instantiated a single-piece class, however, at this time, thread B cannot be prevented from performing instantiation again (because B has already come in). There are two instances, so the implementation of this classic single-piece mode is somewhat flawed.

I have three solutions to the problem of multithreading.

First:

Public class Singleton {Private Static Singleton uniqueinstance; // other useful instance variables here private Singleton () {} public static synchronized Singleton getinstance () {// a synchronized if (uniqueinstance = NULL) {uniqueinstance = new Singleton ();} return uniqueinstance;} // other useful methods here}

Yes, it is solved by adding a thread lock. before entering the getinstance () method, wait for other threads to leave the method before execution, that is, there are no two or more threads entering this method at the same time. But in fact, we only need to synchronize this method for the first time. After the uniqueinstance variable is created, we do not need to synchronize this method, and synchronization will reduce performance, which is a burden.

Second:

Public class Singleton {// create a single piece in the static initialization, ensuring thread security Private Static Singleton uniqueinstance = new Singleton (); Private Singleton () {} public static Singleton getinstance () {return uniqueinstance ;}}

This is the first way to create a single-piece class without delay instantiation. If the burden of creating and running this single-piece class is not heavy, you can use this method to create a single-piece class, after all, it is easy to use.

Third: (I think the best one, but Java 5 or a later version is required)

Public class Singleton {private volatile static Singleton uniqueinstance; private Singleton () {} public static Singleton getinstance () {// breakpoint 1if (uniqueinstance = NULL) {// breakpoint 2 synchronized (Singleton. class) {// breakpoint 3if (uniqueinstance = NULL) {// breakpoint 4 uniqueinstance = new Singleton () ;}} return uniqueinstance ;}}

First, I will explain what volatile is for: it is used in multithreading and synchronizing variables. To improve the efficiency, the thread copies a member variable (such as a) (such as B), and the access to a in the thread is actually B. Only A and B are synchronized in some actions. Therefore, A and B are inconsistent. Volatile is used to avoid this situation. Volatile tells JVM that the modified variables do not keep copies and directly access the primary memory (that is, a mentioned above), but they do not guarantee atomic operations.

It is also explained by two threads a and B. When the single-piece class is not instantiated, thread a and thread B are executed to breakpoint 1 at the same time, and then to breakpoint 2 after judgment, in this case, assume that a takes a step forward, executes to breakpoint 3, and locks the class. Thread B can only wait. After thread a completes judgment, execute breakpoint 4, instantiate a single class, and exit the method to unlock it; thread B executes to breakpoint 3 and locks the class. Then, it judges that the instance uniqueinstance already exists, leaves and unlocks the instance. Some other threads will only execute to breakpoint 1 and will not execute to breakpoint 2. This avoids the performance problems caused by the thread lock.

Note that the pre-lock judgment is required. The pre-lock is to avoid other threads from executing the thread lock method after the instance is created to improve the performance. After the lock, it is to avoid creating multiple instances, otherwise, how many threads will be generated when they enter breakpoint 2.

This is the "double check lock" method.

This is the single-piece mode. If you are interested in other design modes, please check out some of my other blogs.


Single-piece Mode

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.