面试场景: 写一个你认为最好的单例的实现方式
应对: Android端双重校验锁的单例实现
理解: 理解单例的基本原理,写起来就容易多了,可理解为全局只有这一个实例
手写:已经在代码的注释中说明了面试时,可能会延申的几个小问题;理解不透彻的地方,还请多多指教。
public class SingletonMode {
/**
* volatile关键字: 保持内存的可见性--所有线程都能获取的共享内存的最新状态
* 理解:
* 不用volatile的状态: 老板让多个人共同完成一件事(初始状态为进行中),假设
* 其中某一个人完成后,事件状态变成了已完成;但是
* 其他人不知道这件事已完成,认为该事件依然处于进行中
* 这就造成了事情的状态与真实状态不同步的现象。
* 使用volatile的状态:板让多个人共同完成一件事(初始状态为进行中),假设
* 其中某一个人完成后,事件状态变成了已完成;此时
* 其他人立刻从老板那接到了事情已完成的通知,于是都明确了
* 这件事已经完成了。
* volatile的作用:每次读取前必须先从主存刷新最新的值
* 每次写入后必须立即同步回主存当中
*/
private static volatile SingletonMode singletonMode;
//构造函数修饰为private防止在其他地方创建该实例
private SingletonMode() {
}
/**
* 有的代码中会将同步锁synchronized写在方法中,例如:
* public static synchronized SingletonMode getInstance(){.....}
* 造成的弊端就是:多线程每次在调用getInstance()时都会产生一个同步,造成损耗。
* 相应的我们需要保持同步的代码块仅仅就是:
* singletonMode = new SingletonMode();
* 所以只要在该代码处添加同步锁就可以了
* @return
*/
public static SingletonMode getInstance() {
/**
* 此处检测singletonMode == null,是为了防止当singletonMode已经初始化后,
* 还会继续调用同步锁,造成不必要的损耗
*/
if (singletonMode == null) {
// 加锁目的,防止多线程同时进入造成对象多次实例化
synchronized (SingletonMode.class) {
// 为了在null的情况下创建实例,防止不必要的损耗
if (singletonMode == null) {
singletonMode = new SingletonMode();
}
}
}
// 返回实例对象
return singletonMode;
}
}