java设计模式之4—单例模式 结合生活代码理解

通过名字可以看出,此模式大概的意思就是只有一个实例,其实这也是单例模式的中心思想,即一个类的实例化对象是唯一的

定义

保证一个类只有一个实例存在,同时提供能对该实例访问的全局访问方法。

分为以下几种形式

饿汉式
懒汉式
双重检查(多线程访问)

饿汉式
饿汉式,顾名思义,对象很饥饿,无论你获取或者不获取对象实例,我都已经创建好了,我的开的菜馆生意很火爆,于是我就提前做好卖的最好的几道菜,到饭点时就可以直接热热就能上桌,以解放厨师能在饭点时做其他菜,提高效率。

懒汉式
懒汉式,就是对象我暂时不创建,当你需要对象的实例时,我再创建虽然我的菜馆很火爆,但并不是所有的菜都需要提前做好,万一卖不出去就砸手里了,所以当有人点这道菜的时候我再做,这也是可以的

双重检查

双重检查,如果你认为你对多线程是了解的,可以看看这种方式,否则这种方式的理解还是有难度的。这是为多线程考虑的,在懒汉式的基础上加以修改,懒汉式在多线程访问的时候会有问题,当有三个线程同时访问的时候,一个线程获得cpu执行权,正在创建对象,而另两个线程已经通过了对象为null的判断,正在等待执行创建对象,当获得cpu的证行权后立即创建对象,这时候就出问题了,对象不止创建了一次。

一重检查,将对象的创建过程用synchronized同步代码块包裹,加上同步代码块,减少了对象被多次创建的几率,注意是减少,而没有根本解决,同样上面的问题还是会出现,而等待的不是CPU的执行权,而是同步锁的钥匙

二重检查,即在同步代码块中再加一层对象为null的判断,即使有等待同步锁的线程拿到钥匙后(前面持有钥匙的线程已经创建了对象),会再次判断对象是否已经被创建,已经创建了就不会再创建了,而是直接获取。

这样,就会在对象初始创建的时候多线程并发访问也不会出现问题,之后就不会再进入同步代码块当中,因为最外层的判断已经知道对象已经创建好,之后的线程直接获取即可。

实现代码

代码可在码云中下载(包名为d_singleton)
https://gitee.com/XiaoSa12138/java-models

饿汉式

/**
 * 饿汉式
 */
public class Hunger {

	private static Hunger hunger = new Hunger();
	
	public static Hunger getHunger(){
		return hunger;
	}
}

懒汉式

/**
 * 懒汉式
 */
public class Lazy {

	private static Lazy lazy;
	
	public static Lazy getLazy(){
		if (lazy == null) {
			lazy = new Lazy();
		}
		return lazy;
	}
	
}

双重检查

/**
 * 双重检查,解决懒汉式在多线程下的安全问题
 */
public class Check {
	
	private static Check check;
	
	public static Check getCheck(){
		if (check == null) {
			synchronized (Check.class){
				if (check == null) {
					check = new Check();
				}
			}
		}
		return check;
	}

}

猜你喜欢

转载自blog.csdn.net/weixin_42997554/article/details/85224669
今日推荐