单例模式几种写法,安全 不安全 懒汉 饿汉

单例模式几种写法,安全 不安全 懒汉 饿汉

单例模式在平常中运用较多,而且在面试中更是被经常提及
单例模式有几个重点是懒汉模式,饿汉模式,线程安全,线程不安全


这个是最普通的单例模式,这个是懒汉式,线程不安全

//这个是普通的单例模式
public class Singleton{
	private static Singleton instance = null;
	private Singleton(){

	}

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

**懒汉式,线程安全类型**
//这个是线程安全的单例模式
//这个在调用的时候回锁住整个方法,效率不是很好
public class Singleton{
	private static Singleton instance = null;
	private Singleton(){

	}

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

虽然这个是线程安全,但是效率不是很好,因为在任何时候只有一个线程能调用getInstance()方法。


下面我们就使用双重检验锁来解决这个问题。
双重检验锁是对同步块加锁的方法。为什么会称为双重检验,因为有两次对 instance == null的检查,一次中同步块中一次中同步块外部。
为什么在同步块内还要再检验一次?因为可能会有多个线程一起进入同步块外的 if,如果在同步块内不进行二次检验的话就会生成多个实例了。

	//这个是线程安全的是效率比较好的
public class Singleton{
	private static Singleton instance = null;
	private Singleton(){

	}

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







上面的不是都是懒汉模式的,下面我们来介绍一下关于饿汉模式的
饿汉模式 static final field 这种方法也是很简单,只需要将单例的实例声明为static何final变量。这是因为在第一次加载到内存中的就会被初始化,所以创建实例本身是线程安全的。

public class Singleton{
    //类加载时就初始化
    private static final Singleton instance = new Singleton();
    
    private Singleton(){}
    public static Singleton getInstance(){
        return instance;
    }
} 

**静态内部类 stat nested class**
//懒汉式的静态内部类
public class Singleton{
	private static class SingletonInner{
		private static final Singleton INSTANCE = new Singleton();
	}
	private Singleton{

	}

	private static final Singleton getInstance(){
		return SingletonInner.INSTANCE**strong text**;
	}

}

这是目前最好的解法,既是线程安全又无其他的问题。

原文地址:https://www.cnblogs.com/wangshouchang/p/6911975.html