Home  >  Article  >  Java  >  Detailed introduction to singleton pattern

Detailed introduction to singleton pattern

王林
王林forward
2020-08-10 16:29:312538browse

Detailed introduction to singleton pattern

First of all, let’s take a look at the definition of the singleton pattern:

The singleton pattern is one of the simplest design patterns in Java and is a creational pattern. It provides A best way to create objects. The singleton pattern involves a single class that is responsible for creating its own objects while ensuring that only a single object is created.

(Recommended tutorial: java introductory tutorial)

In order to ensure that there is only one object in the memory, avoid frequent creation of objects that cause memory consumption, so that all This singleton object is used wherever this object needs to be called.

Next let’s look at the types of singleton patterns:

1. Lazy style

Lazy style means that the singleton will only be created when it is needed. object.

Lazy-style singleton pattern implementation:

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

There is a problem with lazy-style singleton implementation, that is, how to ensure that only one object is created? If two or more threads determine that singleton is empty at the same time, multiple objects will be created. Therefore we need to solve the thread safety problem.

When it comes to thread safety, what comes to mind is locking. Locking is nothing more than locking on methods or class objects.

//在方法上加锁
public class Singleton {
	private static Singleton singleton;
	private Singleton(){}
	public static synchronized Singleton getInstance() {
    	if (singleton == null) {
        	singleton = new Singleton();
    	}
    return singleton;
	}
}

//在类对象上加锁
public class Singleton {
	private static Singleton singleton;
	private Singleton(){}
	public static Singleton getInstance() {
    synchronized(Singleton.class) {   
        if (singleton == null) {
            singleton = new Singleton();
        }
    }
    return singleton;
	}	
}

These two methods can solve the problem of multi-threads creating singleton objects at the same time, but each time you obtain the object, you need to acquire the lock first, and the concurrency performance is poor. Therefore, optimization is still needed. The optimization goal is: if there is no instantiated object, lock and create it. If there is an instantiated object, return directly.

(Learning video recommendation: java course)

For locking on a method, locking is required regardless of whether there is an instantiated object. Therefore, what we need to optimize is to lock the class object.

//DCL单例模式(Double Check + Lock)
public class Singleton {
	//volatite关键词防止指令重排序,下文介绍
	private static volatile Singleton singleton;
	private Singleton(){}
	public static Singleton getInstance() {
	//如果singleton不为空,则直接返回对象,若多个线程发现singleton为空,则进入分支
		if (singleton == null) {
		//多个线程同时争抢一个锁,只有一个线程能成功,其他线程需等待
			synchronized(Singleton.class) {
			//争抢到锁的线程需再次判断singleton是否为空,因为有可能被上个线程实例化了
			//若不为空则实例化,后续线程再进入的时候则直接返回该对象
			//对于之后所有进入该方法的线程则无需获取锁,直接返回对象   
        	if (singleton == null) {
           		singleton = new Singleton();
        	}
    		}
		}
    	return singleton;
	}	
}

The volatile keyword is added to the above code to prevent instruction reordering.

2. Hungry Chinese style

Hungry Chinese style means that the singleton object is created when the class is loaded.

Hungry Chinese style singleton pattern implementation:

public class Singleton {
	private static final Singleton singleton = new Singleton();
	private Singleton(){
	
	}
	public static Singleton getInstance(){
		return singleton;
	}

Summary:

Lazy Man style: instantiate objects only when needed. In development, if the memory requirements are high, that is Using the lazy style, in a multi-threaded environment, you should use the DCL singleton mode. Using the DCL singleton mode solves the problems of concurrency security and low performance. If you add the volatile keyword, it can also prevent NPE exceptions caused by instruction reordering.

Hungry Chinese style: The object has already been instantiated when the class is loaded. If the memory requirements are not high, use the Hungry Chinese style. It is simple, not error-prone, and does not have any concurrency security and performance issues.

The above is the detailed content of Detailed introduction to singleton pattern. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:csdn.net. If there is any infringement, please contact admin@php.cn delete