设计模式——单例模式(推荐静态常量、静态代码块、静态内部类、双重检查、枚举的方式创建对象)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_32603969/article/details/102690331

一、概览

 

二、单例模式

(1)、饿汉式(静态常量)——推荐使用

package Singleton;

public class Singleton1 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Singleton instance1 = Singleton.getInstance();
		Singleton instance2 = Singleton.getInstance();
		System.out.println(instance1 == instance2);
		System.out.println(instance1.hashCode());
		System.out.println(instance2.hashCode());
	}

}

//饿汉式
class Singleton {
	//私有构造器,防止别人去new。
	private Singleton() {}
	
	private final static Singleton instance = new Singleton();
	public static Singleton getInstance() {
		return instance;
	}
}

运行结果:

true
366712642
366712642

因为静态属性在类加载的时候就被赋了值,因此在后续每次调用中都是同一个对象。


(2)、饿汉式(静态代码块)——推荐使用

将实例化放到静态代码块中即可。


(3)、双重检查——推荐使用

package Singleton;

public class Singleton1 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Singleton instance1 = Singleton.getInstance();
		Singleton instance2 = Singleton.getInstance();
		System.out.println(instance1 == instance2);
		System.out.println(instance1.hashCode());
		System.out.println(instance2.hashCode());
	}

}


class Singleton {
	//私有构造器,外部不能new。
	private Singleton() {}
	
	// 线程将值一改变后就刷到主存去,即这个值改变后对其他线程来说是可见的。
	private static volatile Singleton instance;
	

	public static Singleton getInstance() {
		if(instance == null) {// c\d\e\线程来访问时就被过滤掉,从而不执行线程同步节约资源
			synchronized (Singleton.class) {
				if(instance == null) {// a线程实例化后将b线程过滤掉
					instance = new Singleton();
				}
			}
		}
		return instance;
	}
}

(4)、静态内部类——推荐使用

package Singleton;

public class Singleton1 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Singleton instance1 = Singleton.getInstance();
		Singleton instance2 = Singleton.getInstance();
		System.out.println(instance1 == instance2);
		System.out.println(instance1.hashCode());
		System.out.println(instance2.hashCode());
	}

}

class Singleton {
	//私有构造器,外部不能new。
	private Singleton() {}
		
	//外部类加载的时候不会加载内部内
	private static class SingletonInstance{
		private static final Singleton instance = new Singleton();
	}
	
	//再调用内部内属性的时候加载一次内部内
	public static Singleton getInstance() {
		return SingletonInstance.instance;
	}
}

(5)、懒汉式(线程不安全)——不推荐使用

package Singleton;

public class Singleton1 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Singleton instance1 = Singleton.getInstance();
		Singleton instance2 = Singleton.getInstance();
		System.out.println(instance1 == instance2);
		System.out.println(instance1.hashCode());
		System.out.println(instance2.hashCode());
	}

}

//懒汉式
class Singleton {
	//私有构造器,外部不能new。
	private Singleton() {}
	
	private static Singleton instance;
	
	// 使用到的时候才去创建实例,即懒汉式,线程不安全
	public static Singleton getInstance() {
		if(instance == null) {
			instance = new Singleton();
		}
		return instance;
	}
}


(6)、懒汉式(线程安全)——不推荐使用

加上synchronized即可。

(7)、枚举方式

枚举类里面的每一个元素表示这个枚举类的不同的实例。

package Singleton;

public class Singleton1 {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Singleton instance1 = Singleton.INSTANCE;
		Singleton instance2 = Singleton.INSTANCE;
		System.out.println(instance1 == instance2);
		System.out.println(instance1.hashCode());
		System.out.println(instance2.hashCode());
	}

}

enum Singleton {
	INSTANCE;
	public void method() {
		System.out.println("方法!");
	}
}

猜你喜欢

转载自blog.csdn.net/qq_32603969/article/details/102690331