Singleton - on

What singleton pattern is?

Singleton design pattern appears to be a class of the most simple, and it is only one class in the class diagram. Its main principle is that the class is responsible for creating your own objects, and only a single object is created.

Use Singleton pattern?

For those who only need a target, such as: the thread pool (threadpool), caching (cache), Registry (registry) of the object.

Four kinds of one-implemented method of embodiment mode

Classic singleton

Implementation code

public class Singleton {
    private static Singleton instance;
	//构造函数为private, 防止该类的实例被错误的创建
    private Singleton() {
    }

    public static Singleton getInstance() {
        //保证实例只会被创建一次
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

problem

When multiple threads of execution will not result in line with expectations

// 实现Runnable接口
public class T implements Runnable{
    @Override
    public void run(){
        Singleton instance = Singleton.getInstance();
        System.out.println(Thread.currentThread().getName()+"  "+instance);
    }
}
// 测试类
public class Test {
    public static void main(String[] args) {
        Thread t1 = new Thread(new T());
        Thread t2 = new Thread(new T());
        t1.start();
        t2.start();
    }
}

operation result:

Result analysis:

    public static Singleton getInstance() {
        //保证实例只会被创建一次
        [0]if (instance == null) {
            [1]instance = new Singleton();
        }
        [2]return instance;
    }

Suppose that two threads are called t0, t1, when interventions by manual debugging tools to execute the order:

t0[0]->t1[0]->t0[1]->t0[2]->t1[1]->t1[2]

Will result in two examples, does not comply with the requirements of singleton

Locked singleton

Implementation code

public class Singleton {
    private static Singleton instance;

    private Singleton() {
    }

    // 使用synchronized进行同步,对Singleton类加锁
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

problem

While solving the problem through multi-threaded synchronization method, but synchronous influence the performance of the execution. And examples only created once, but the method by which each call to getInstance () function need to be synchronized, very cumbersome.

Eager singleton

Implementation code

public class Singleton {
    // 利用静态变量,实现单例
    private static final Singleton instance = new Singleton();

    //* 虽然不调用构造函数,需要防止系统自动创建public的构造函数
    private Singleton() {
    }

    public static Singleton getInstance() {
        return instance;
    }
}

problem

The program very good solution to the problem caused by multi-threading and synchronization method is not used. When the class loading time will create its instances, there is no delay loading, may lead to waste of memory.

Double-checked locking

Implementation code

public class Singleton {
    // 实现细节1:volatile关键字
    private static volatile Singleton instance;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                // 实现细节2:两次判断是否为null
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

Implementation details

Implementation details 1: why should we increase the volatile keyword?
instance = new Singleton()	

Since this code is not above an atomic operation, the actual experience of the three steps

  1. To allocate memory objects
  2. Object Initialization
  3. Set instance referenced memory address at the just distribution of

Without the use of volatile keyword, JVM may cause reordering program execution sequence which is 1-> 3-> 2

Suppose thread t0, t1, may occur following:

  1. t0 allocate memory for objects
  2. t0 instance provided just references to allocated memory address [case instance! = null]
  3. t1 is determined whether the instance is null
  4. t1 first visit objects
  5. t0 initialize objects
  6. t0 first visit objects

Use the volatile keyword use shared variables modified cache coherency protocol to ensure the visibility of memory

Implementation details 2: Why use two inspections

Without the use of checks, the assumption that there is a thread t0, t1, may occur following:

  1. t0 is determined whether the instance is null
  2. t1 is determined whether the instance is null
  3. t0 enter the critical section to create an object instance
  4. t0 returns
  5. t1 enter the critical section to create an object instance
  6. t1 return

At this time t0 and t1 create two different instances, a single violation of the principle of the embodiment

problem

Code complexity, in the JDK1.4 and earlier versions of Java, the realization of the volatile keyword will lead to double check the lock failure

Inner classes

public class Singleton {
    
    private Singleton() {
    }

    private static class SingletonHolder {
        private static Singleton instance = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonHolder.instance;
    }
}

By problem that the method can multithreading, and because no locks have superior performance under high concurrency conditions. And implementation of a static variable which is different from the class, only the first call to getInstance () function of time will create an instance, so the situation will not be a waste of memory.

common problem

To achieve the above appears to be very perfect, but there are still some issues

  1. Serialization destruction singleton
  2. Reflection attack damage singleton

Guess you like

Origin www.cnblogs.com/YuanJieHe/p/12616921.html