多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] # 应用场景 系统/应用只需要一个实例对象,确保对象的唯一性。 [https://blog.csdn.net/u011499747/article/details/48194431](https://blog.csdn.net/u011499747/article/details/48194431) 双重检查 第一次检查时候,没有锁定,看这个有没有被实例化,有就直接返回 第二次检查,表面是没有初始化才第二次,锁定,初始化,返回 # 分析 1. 不让其他程序new该类对象,咋办?——可以将类中的构造函数私有化。 2. 在本类中new一个对象。 3. 定义一个方法返回该对象,让其他程序可以获取到。之所以定义方法访问,就是为了可控。 # 饿汉式单例模式 ~~~ public class Single { // 创建一个本类对象 private static final Single s = new Single(); // 构造函数私有化 private Single(){} // 定义一个方法返回该对象,让其他程序可以获取到。之所以定义方法访问,就是为了可控 public static Single getInstance() { return s; } } ~~~ 以上我们一般称之为**饿汉式单例模式**,单例模式有两种不同的实现方式,下面是**懒汉式单例模式(也可称之为延迟加载方式)** 的代码体现 # 懒汉式单例模式 ~~~ public class Single { // 创建一个本类对象 private static /*final*/ Single s = null; // 别加final,死! // 构造函数私有化 private Single(){} // 定义一个方法返回该对象,让其他程序可以获取到。之所以定义方法访问,就是为了可控 public static Single getInstance() { if (s == null) s = new Single(); return s; } } ~~~ 上面代码还有一些瑕疵,因为在多线程并发访问时,会出现线程安全问题。 加了同步就可以解决问题,无论是同步函数,还是同步代码块都行。 但是效率低了,怎么解决效率低的问题呢?可以通过if对单例对象的双重判断的形式来解决。 ~~~ public class Single { private static Single s = null; private Single() {} public static Single getInstance() { if(s == null) { synchronized(Single.class) { if(s == null) s = new Single(); } } return s; } } ~~~ 面试时,可能会问懒汉式与饿汉式有什么不同?答曰懒汉式的特点用于实例的延迟加载。又可能会接着问懒汉式的延迟加载有没有问题?答曰有,如果多线程访问时会出现安全问题。又问怎么解决呢?答曰可以加同步来解决,用同步代码块和同步函数都行,但是稍微有一些低效,用双重判断的形式能解决这个效率问题。最后可能会问加同步时,使用的锁是哪一个?答曰该类所属的字节码文件对象。