今天记录一下单例模式的学习心得,虽然都是烂大街的东西,不过记录一下总比不记录好。
关于单例模式的概念和用途我就不赘述了,百度一下,各种专业解释,我今天主要用代码来简单说明一下
一、饿汉模式
public class Person {
private static final Person person = new Person();
private Person() {
}
//获取Person实例
public static Person getInstance() {
return person;
}
}
很明显,Person的实例在调用getInstance的时候就已经创建好了,调用getInstance直接使用Person实例即可。叫这种模式为饿汉模式,是因为创建Person的实例很着急,在调用getInstatnce之前就已经存在了
二、懒汉模式
public class Person {
private static Person person;
private Person() {
}
//获取Person实例
public static Person getInstance() {
if(person==null) {
person = new Person();
}
return person;
}
}
和饿汉模式明显不同的地方是Person的实例在调用getInstance的时候才创建的,为了防止person的二次创建为不同的对象,需要添加一个null的判断,但是这个方法是线程不安全的,而双重守护就是针对这种线程不安全的问题
三、双重守护
public class Person {
private static Person person;
private Person() {
}
//获取Person实例
public static Person getInstance() {
if(person==null) {
synchronized (Person.class) {
if(person==null) {
person = new Person();
}
}
}
return person;
}
}
双重守护是解决线程安全的最终版本,之前还有很多进阶版,我也不写了。getInstance方法中的第一层person==null大家应该都很理解,但是第二层的person==null很多人就很费解了,认为有同步锁不就行了吗?其实不然,因为锁在这个同步的位置也可能是两个线程,如果没有第二个person==null,一个线程创建完之后跳出去,另一个会再次创建,这样依然会线程不安全。双重守护就解决了这个问题