Optimization of the single idler embodiment

Lazy singleton (plus synchronized keyword) in multi-threaded

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

Inefficiency, requires synchronization method invocation of getInstance

 

Optimization 1

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

Without this instance, you need only add synchronized code block to the code created on the instance, if the instance already exists, return directly to that instance.

But in that way it can not play the role of thread synchronization, because due to instantiate an object, memory object will be reordered,

It is likely to lead to a multi-threaded execution time to time if the judgment has not been initialized or not get a null object is initialized but not yet completed.

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

Advantages and disadvantages: This Double-Check-Lock manner whether two instances of judgment is empty, because the volatile keyword specifies a ban on re-ordering, volatile to ensure the visibility of the variable changes, but does not guarantee atomicity.

A thread changes to the variable, and another thread can immediately read the value of this modification, volatile happens-before is to follow the principles of this multi-threaded environment, carried out to determine if the time has been able to get a complete example of good Object,

While other thread if the judge, returned directly to the object. In this way we can achieve the security thread, and in that way also to achieve a lazy-loading, high efficiency.

Is there a way to implement a thread-safe manner not in use lock, synchronized the singleton pattern here? The answer is, yes, that is the use of CAS.

CAS What is it? Compare And Swap, as the name suggests is to compare and exchange. CAS entry is optimistic locking technique, which consists of three parameters, namely, V (value to be updated), E (expectation), N (new value),

When V and E are not the same, indicating that another thread has already updated done, at which time the thread does not perform the update operation, or try again attempts to modify the value of V read value again, the operation may choose to give up. If V and E are equal, the current thread can modify the value of V,

CAS is to perform the operation. CAS no lock operation involved, but for the other threads to shared resources for the operations made a deal. Since the CAS was not involved in the lock, so the operation thread for a shared resource deadlock does not occur, it can be said CAS innate immune deadlock.

public  class the Singleton {
     Private  static  Final AtomicReference, <the Singleton> INSTANCE = new new AtomicReference, <the Singleton> ();
     Private the Singleton () {}
     public  static the Singleton the getInstance () {
         for (;;) { // Any number of spin loop, If the CAS has failed, execution CPU overhead is consumed very serious 
            the Singleton Singleton = INSTANCE.get ();
             IF ( null =! Singleton) {
                 return Singleton; 
            } 
            Singleton = new new the Singleton ();
            IF (INSTANCE.compareAndSet ( null , Singleton)) { // this instance is null, as it replaces the current instance Singleton 
                return Singleton; 
            } 
        } 
    } 
}

Shortcoming Analysis: The way to use CAS achieve thread-safe, compared to the traditional lock mechanism to achieve it, CAS relies on the underlying hardware (CPU's instruction CAS) to achieve, it does not require frequent thread switching and obstruction caused by resources additional consumption.

However, this approach is flawed, CAS spin cycle for a long time if not successful, then it will bring a very large CPU execution cost. Another point is that if N threads to simultaneously execute singleton = new Singleton () when, at the same time it will create a lot of examples, very OOM can happen.

CAS disadvantages: First of CAS ABA problem, this can be solved by adding a version number or timestamp, after completion of the comparison value in memory, and then compare the version numbers or timestamps are the same.

CAS spin operation, if CAS long-term successful, would have been retried, it would seriously increase the cost of execution of the CPU. JDK1.6 enabled by default after the spin (--XX: + UseSpinning),

JVM can be solved by setting the frequency of the spin operator CAS (-XX: PreBlockSpin = 10, the number of spins JVM default is 10), when more than a specified number of times, failure of automatic exit. Another adaptive spin lock spin time is no longer fixed,

According to a state before the meeting with a lock spin time and the lock owner to decide.

Limitations of the CAS functions, CAS can only guarantee the value of a single atomic memory, in atomic java does not necessarily guarantee thread safety, but also volatile to ensure orderly to achieve thread safety.

When it is necessary to ensure that the values ​​of the plurality of memory, CAS can not do anything, you can be seen using pessimistic locking. So in a relatively high probability of concurrent conflict environments, try not to use CAS.

Secondly, the core of the CAS is to rely on CompareAndSwap Unsafe class can call the underlying resource direct () method implemented using java can only be used in the relevant class under the Atomic package, limitations relatively large.

Guess you like

Origin www.cnblogs.com/hetaoyuan/p/11429900.html