设计模式之单例设计模式

上次写了工厂设计模式,那么今天就来聊聊单例设计模式。

那么什么是单例设计模式呢,简单来说就是确保一个类只能创建一个实例,并且能提供这个类的访问。

实现:使用一个静态私有构造函数,一个静态变量以及一个静态公有函数来实现。

下面举个栗子吧:在这里插入图片描述
假设一个帝王,她同时拥有三个妃子,然后呢这个帝王能干嘛呢?每晚到不同的妃子住处让妃子侍寝是吧,那么既然帝王只有一个,而不同的妃子住在不同的地方,而这个帝王很显然不是什么荒淫无度的君王,那么也就是说每晚只有一个妃子能够获得这个帝王是吧。

好,现在让我们来看看具体怎么实现:

创建帝王类,

public class King {
	private static King king = null;
	
	private King() {
		
	}
	
	public static King getKingToSleep() {
		if(king == null) {
			king = new King();
		}
		return king;
	}
}

这就是单例设计模式的创建方式之一,在调用时再创建对象,所以也被称为懒汉式,但这种方式有个显而易见的缺陷那就是线程不安全,试想如果有多个线程同时访问getKingToSleep()方法,如果前一个线程king为空判定为真,但还未得到new King()的对象而下一个线程也进入这个方法此时king为空依然为true,此时就会创建两个对象,不符合我们单例设计模式的原则,因此这种方式是线程不安全的,那么怎么解决呢?很简单只要加上线程锁就行了。

public class King{
	private static King king = null;

	private King() {
		
	}
	
	public static synchronized King getKing() {
		if(king == null) {
			king = new King();
		}
		return king;
	}
}

上面就是加了线程锁后的代码,其实就是synchronized,表示这个类一次只允许一个线程进入。当然这样效率就会很低,因为每次调用getKing()方法都需要加锁。

下面再为大家介绍一种线程安全效率也低的写法吧:

public class King{
	private static King king = null;

	private King() {
		
	}
	
	public static  King getKing() {
		if(king == null) {
			synchronized(King.class) {
				if(king == null) {
					king = new King();
				}
			}
		}
		return king;
	}
}

当然这话种写法也有一个缺点,那就是可能出现king = new King();这个地方并未被初始化但分配了内存地址,也就是说这样第二个线程访问时就会默认取到了实例,但这个实例可能是不完整的。

最后再给大家介绍一种简单好用的创建单例的方式,饿汉式:

public class King {
	private static King king = new King();
	
	private King() {
	}
		
	public static King getKingToSleep() {
		return king;
	}
}

而这种方式的弊端也很显而易见,那就是每次加载类都会创建实例,会产生大量垃圾对象。

最后再来介绍一种比较稳妥的方式,那就是内部静态类的方式

public class King {  
    private static class KingHolder {  
    private static final King king = new King();  
    }  
    private King (){}  
    public static final King getKingToSleep() {  
    return KingHolder.king;  
    }  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值