Java multithreaded Programming 6--single-case mode and multi-threading--a single-case pattern design 1

Source: Internet
Author: User

In the standard 23 design patterns, the single case design pattern is more common in the application. However, in the general introduction of this mode of teaching materials, most of them are not combined with multithreading technology as a reference, which results in the use of multithreading technology in the singleton mode, there will be some unexpected situation, such code if in the production environment anomalies, can have disastrous consequences.

1. Load Now/"A Hungry man mode"

What is load now? The immediate load is also known as the "a Hungry Man mode", where the object is created when the class is used, and the common implementation is to instantiate it directly.
Load Now/"A Hungry Man mode" is the instance that was created before calling the method, and look at the implementation code.

/** * This code is loaded immediately, the disadvantage is that there is no other instance variable * because the getinstance () method is not synchronized, a non-thread-safe section may occur */public class MyObject {    private static MyObject m Yobject = new MyObject ();    Private MyObject () {} public    static MyObject getinstance () {      return MyObject;    }}
public class MyThread extends Thread {    @Override public    void Run () {        System.out.println ( Myobject.getinstance (). Hashcode ());}    }
public class Run {public    static void Main (string[] args) throws ParseException {        MyThread t1 = new MyThread (); 
   mythread t2 = new MyThread ();        MyThread t3 = new MyThread ();        T1.start ();        T2.start ();        T3.start ();    }}
1032010069
1032010069
1032010069
The hashcode that the console prints is the same value, stating that the object is the same, and that an immediate-loading singleton design pattern is implemented.

2. Lazy loading/"lazy mode"

What is deferred loading? Lazy loading, also known as lazy mode, is the instance that is created when the Get () method is called, and the common implementation is to instantiate the new in the Get () method.

Lazy Load/Lazy mode is the instance that was created when the method was called. Although only one instance is taken in a thread, multiple instances are taken out in a multithreaded environment.

public class MyObject {    private static MyObject MyObject;    Private MyObject () {} public    static MyObject getinstance () {        if (MyObject = = null) {            //impersonation do some preparatory work before creating the object            try {                thread.sleep;            } catch (Interruptedexception e) {                e.printstacktrace ();            }            MyObject = new MyObject ();        }        return myObject;}    }
Custom threads and run-similar, the result
658705244
580835623
1791140146
The console prints 3 types of hashcode, stating that 3 objects were created, not Singleton, which is the "wrong singleton pattern". How to solve it? Look at the solution first.

2.1. Deferred loading/"lazy mode" solution

(1) Declaration synchronized keyword
Now that multiple threads can enter the human getinstance () method at the same time, you only need to declare the SYNCHRONIZED keyword to the getinstance () method.

public class MyObject {    private static MyObject MyObject;    Private MyObject () {}    /**     * This kind of synchronized lock method is very inefficient, although it is running synchronously, but each call to getinstance (), the object must be locked     * And the next thread wants to get the object, it must wait for the last thread to release the lock before it can continue execution.     *    /public synchronized static MyObject getinstance () {        if (MyObject = = null) {            //impersonation do some preparatory work            before creating 2 objects try {                thread.sleep;            } catch (Interruptedexception e) {                e.printstacktrace ();            }            MyObject = new MyObject ();        }        return myObject;}    }
Custom threads and run-similar, the result
1791140146
1791140146
1791140146

2.2. Try synchronizing the code block

The synchronous method is to lock the whole method, which is not disadvantageous to the operation efficiency. Is it possible to change to a synchronous block of code? First look at an example of a less efficient

public class MyObject {/    * * holds a private static instance that is protected from reference and is assigned null here to enable lazy loading */    private static MyObject MyObject = null;    Private MyObject () {} public    static MyObject getinstance () {        try {/            * * This notation is equivalent to:            * public synchronized Static MyObject getinstance () is            very inefficient * */            synchronized (myobject.class) {                if (MyObject = = null) {
   //simulation To do some preparatory work before creating the object                    Thread.Sleep ();                    MyObject = new MyObject ();}}        } catch (Interruptedexception e) {            e.printstacktrace ();        }        return myObject;}    }
Custom threads and run-similar, the result
658705244
658705244
658705244

Synchronous code blocks can be synchronized for some important code, while others do not need to be synchronized. In this way, efficiency can be greatly improved at run time.

Using the DCL dual detection lock mechanism to implement, continue to modify this code:

public    Class MyObject {/* holds a private static instance that is protected from reference and is assigned null here to enable lazy loading */private static MyObject MyObject = null;            Private MyObject () {}//uses a dual detection mechanism to solve the problem, ensuring asynchronous execution without the need for synchronous code, and ensuring that the effect of a singleton is static MyObject getinstance () {try {                if (MyObject = = null) {//simulate doing some preparatory work before creating the object Thread.Sleep (3000);                Separate synchronization for some important code!!!                    Synchronized (Myobject.class) {//If this is not the case, the same instance object cannot be reached in multi-threaded situations!!!                    if (MyObject = = null) {MyObject = new myObject ();        }}}} catch (Interruptedexception e) {e.printstacktrace ();    } return myObject; }}
1791140146
1791140146
1791140146
Using the double check lock feature, successfully solved the problem of multi-threading in "lazy Mode". DCL is also a solution used by most multithreading in conjunction with a singleton pattern.

Java multithreaded Programming 6--single-case mode and multi-threading--a single-case pattern design 1

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.