本文讲解GOF-23种设计模式其中的单例模式。
单例模式说难吧,其实只有那么几句代码。
说简单吧,其实也要深入理解才能了解它的原理,废话少说,看代码
一、饿汉式写法
/**
* 作者: Created by AdminFun
* 邮箱: 614484070@qq.com
* 描述: 饿汉式单例
* 这种写法是最简单、也算是比较完美的写法,但是这种写法有一些缺点:
* 1、instance的初始化是在类加载的时候完成的,所以不管你用不用都会初始化,可能造成资源浪费。
* 2、如果初始化instance需要依赖其他的数据,那么这里就不能保证在初始化之前准备好。
* 相比于饿汉式写法,有一种更加优美的写法,那就是懒汉式写法 {@link CarHelper1}
*/
public class CarHelper {
private static final CarHelper instance = new CarHelper();
private CarHelper() {
}
public static CarHelper getInstance() {
return instance;
}
}
二、懒汉式写法
/**
* 作者: Created by AdminFun
* 邮箱: 614484070@qq.com
* 描述: 懒汉式单例
*/
public class CarHelper1 {
/**
* volatile 关键字的作用是禁止指令重排,用volatile修饰之后,
* 对instance的读写操作就有一个内存保障,保证在完成写之前不会被调用读。
* <p>
* 想要了解上面一句话,则需要了解JVM中实例化执行过程:
* 1、分配内存
* 2、初始化成员变量,形成实例
* 3、将对象指针指向该内存
* 在多线程操作的时候,以上3个步骤可能会被交叉执行,造成错误内存,volatile就是用来解决这个问题的。
* 不过在平常的一般开发中我们并没有这么严格的要求单例写法,因为在APP开发中很少遇到多线程操作或者我们根本不在乎这个问题
*/
private static volatile CarHelper1 instance;
/**
* 构造方法私有是保证不被外部调用
*/
private CarHelper1() {
// 可以根据需求初始化自己需要的内容
}
/**
* 使用双重判断 + 线程锁
* 双重判断:是为了提升效率,毕竟synchronized算是一个重量级线程锁,如果能在线程锁外面就拦截多线程,则会降低内存消耗
* 线 程 锁:保证只能有1个线程执行锁内操作
*/
public static CarHelper1 getInstance() {
if (instance == null) {
synchronized (CarHelper1.class) {
if (instance == null) {
instance = new CarHelper1();
}
}
}
return instance;
}
}
网友评论