【偷学设计模式之创建型模式】单例 singleton ,单例只知道懒汉和饿汉??99%的人都知道了,你还不进来看?!

单例模式 singleton

可理解为:一个类只有一个实例.
单例模式相对来说比较简单,这里直接上代码直观感受一下。

实现

1.饿汉式

实现:

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

使用:

public class JustTaskMain(){ 	public static void main(String[] args){ 		Singleton s = Singleton.getInstance(); 	} } 

解释:

饿汉式写法,简单暴力,便于理解和编写

  1. 声明 private 无参构造方法,阻止外部实例化
  2. 声明唯一变量 INSTANCE 并实例化
  3. 提供静态方法访问获取 INSTANCE

这种写法的缺点在于,该单例类不管是否使用,在加载的时候就会进行实例化。
有点浪费资源,但是我们大多数情况并不 care 这种问题,所以这种简单易懂的写法也是推荐使用的。

2.懒汉式

实现:

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

使用:

public class JustTaskMain(){ 	public static void main(String[] args){ 		Singleton s = Singleton.getInstance(); 	} } 

解释:

不同于饿汉式,懒汉式是比较完美的一种写法,当然其实现起来会比较复杂,要考虑多线程的情况。

  1. volatile 声明唯一实例,避免即时编译器指令重排导致可能发生的返回空对象的情况,即地址不为空,但还未实例化完成,此时 INSTANCE == null 返回的是 true 。
  2. public class Singleton { private Singleton() { } private static class InnerSingleton { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return InnerSingleton.INSTANCE; } }

    使用:

    public class JustTaskMain(){ 	public static void main(String[] args){ 		Singleton s = Singleton.getInstance(); 	} } 

    这里继续拓展单例类的设计,使用内部类的方式也可以做到使用时加载,且 JVM 会帮我们保证线程安全。

    1. 声明 InnerSingleton 并在其中声明外部类实例并初始化,利用类加载特性,在加载过程中不会加载内部类,而通过外部方法获取实现了使用时加载。

    4.枚举

    实现:

    public enum Singleton {     INSTANCE; } 

    使用:

    public class JustTaskMain(){ 	public static void main(String[] args){ 		Singleton s = Singleton.INSTANCE; 	} } 

    利用枚举特性可以简单而优雅的实现单例,如上。

    其缺点大概就是,通常来说我们都是使用 class ,而使用 enum 来定义单例感觉上有些别扭。

    总结

    以上 4 种单例的实现方式,在工业级别的使用上都是没有问题的,在实际的选用中结合你工程的代码风格,选择最合适的即可。

    其实在现在我们实际开发中大多数也不用自己定义单例了,基本都由框架实现好了,如 Spring 框架等。

    希望本文对你有所帮助,同时 欢迎添加个人微信 dyinggq 一起交流学习~~

    我是 dying 搁浅 ,我始终期待与你的相遇。无论你是否期待,潮涨潮落,我仅且就在这里…

    我们下期再见~
    【偷学设计模式之创建型模式】单例 singleton ,单例只知道懒汉和饿汉??99%的人都知道了,你还不进来看?!