JAVA单例模式简单讲解

作者:Flieny 撰写日期:20190428
使用工具和技术:MyEclipse10、JDK1.7

在学习单例模式的时候,先了解一下它的适用场景。

  1. 需要生成唯一序列的环境(如淘宝订单)
  2. 需要频繁实例化然后销毁的对象(直播弹幕)
  3. 创建对象时耗时过多或者耗资源过多,但又经常用到的对象
  4. 方便资源相互通信的环境

 目前有五种方式可以实现单例,它们分别是饿汉式、懒汉式、Double CheckLock双重锁机制、静态内部类、枚举类。


 饿汉式,它在加载类的时候就首先创建好了一个对象实例,然后等待着调用,所以它叫饿汉式是有原因的,它很像饿汉一样,不管三七二十一先吃饱了再说,然后不管你调不调用,我都创建好了给你。
 优点是线程安全的,调用效率高,但是不能延时加载。

public class SingletonOne{
	//实例化这个类	SingletonOne自身这个类
	//隐藏的自身的静态的实例
	//final可以不用,但是在饿汉式这里需要使用final来保证安全
	//饿汉式就是一加载就会实例自身
	private static final SingletonOne INSTANCE=new SingletonOne();
	//第一步 private私有	隐藏构造器
	private SingletonOne(){	}
	//第二步 把这个实例在定义一个私有的静态变量来放自身的实例
	
	//第三步 创建静态方法,让外部可以获取实例
	public static SingletonOne getInstance(){
		return INSTANCE;
	}
}

 懒汉式,顾名思义,因为它在你使用啊这个对象的时候,它才会去检查这个对象是否存在,如果没有创建就马上创建,如果已经调用了,那么它就会返回这个实例,因此它被称为懒汉式。
 优点是线程安全的,能延时加载,但是调用效率不高。

public class SingletonTwo {
	//类初始化时,不初始化这个对象(延时加载,真正用的时候在创建)
	private static SingletonTwo instance;//静态实例
	private SingletonTwo(){}
	//方法同步,调用效率低
	//创建静态工厂方法,让外部可以获取实例
	//synchronized 同步
	public static synchronized SingletonTwo getInstance(){
		if(instance == null){//如果这个实例等于空
			instance= new SingletonTwo();//懒汉式就是你不去调用,就不会new一下,创建实例给你
		}
		return instance;
	}
}

 Double CheckLock 双重锁机制,它是由懒汉式单例上发展而来的,但由于JVM底层模型的原因,导致了它在执行若干次的时候会出错一次,就是这一次的出错会带来毁灭性的打击,因此不建议使用。

public class SingletonThree {
	private volatile static SingletonThree instance;
	//私有化构造器
	private SingletonThree(){
		
	}
	//静态工厂方法,双重锁判断机制
	public static SingletonThree newInstance(){
		if(instance==null){ //如果instance为空
			synchronized (SingletonThree.class){
				//SingletonThree.class (锁)
				//然后就同里面的一部分代码
				//谁进来就先把下面的代码锁住用完再说
				//然后后面来的只能等待第一个进去的用完
				if(instance==null){
					instance=new SingletonThree();
				}//保证这段代码只能执行一次,只new一次就能保证是单例模式
			}
		}
		return instance;
	}
}

 静态内部类,在类里面定义一个类叫做内部类,它主要会先把空间加载出来,但不会完全的加载出来,只要你在使用的时候才会完全的将内部类加载出来。
 优点是线程安全的,调用效率高,可以延时加载。

public class SingletonFour {
	//第二步 静态内部类
	private static class SingletonClassInstance{
		//只会将空间加载 但不会完全加载
		//只有使用的时候才会完全加载
		//只要使用的时候就会将内部类加载出来
		private static final SingletonFour instance =new SingletonFour();
	}
	//第一步 私有化构造器
	private SingletonFour(){
		
	}
	//第三步 静态工厂方法
	public static SingletonFour getInstance(){
		return SingletonClassInstance.instance;//调用内部父类的成员变量
	}
}


 枚举类,是单利模式中的一种,它是受到JVM底层保护的,JVM会在它执行的时候会保证此方法只能被调用一次,它的优点是能天然的防止反射和反序列化。

public class SingletonFive {
	private SingletonFive(){
		
	}
	//使用枚举
private static enum Singleton{
	INSTANCE;
	
	private SingletonFive singleton; //私有化
	//JVM会保证此方法绝对只能调用一次
	private Singleton(){
		singleton =new SingletonFive();//构建的时候new一下
	}
	public SingletonFive getInstance(){
		return singleton;
	}
}
	//静态工厂方法 调用了Singleton→INSTANCE→getInstance
	public static SingletonFive getInstance(){
		return Singleton.INSTANCE.getInstance();
	}
}


 总结:以上就是学习单例模式的过程了,注意Double CheckLock 双重锁机制是已经过时的单例,一个大神发现了它的问题,它在执行若干此时会出错一次,不要小看这一次,也许就是这一次就可以将整个系统搞崩溃,如银行,银行在操作的时候出现一次错误,就会遭到毁灭性的打击。

发布了29 篇原创文章 · 获赞 51 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_35426391/article/details/89630889
今日推荐