单例模式是最简单的设计模式之一,属于对象创建模式,主要保证一个类只能有一个实例.
单例模式其中的实现又分为饿汉式与懒汉式
饿汉式
饿汉式就是在服务器启动时就进行了创建实例对象,而它的特点是线程安全,机构简单.但是容易产生内存垃圾(一开始就进行了初始化,而该实例可能并没有用到)
模拟代码:
/**
* @author 嘿嘿嘿1212
* @version 1.0
* @date 2020/2/21 19:17
*/
public class Singleton {
//饿汉式
private static Singleton instance = new Singleton();
private Singleton() {
}
public static Singleton getInstance() {
return instance;
}
}
懒汉式
懒汉式就是说在服务器启动并不进行创建实例,而是在真正调用时才会进行创建实例对象(也就是延迟初始化),而实际上有两种实现方式.
简单实现(线程不安全)
在严格意义上并不是单例模式,存在线程不安全问题,
模拟代码:
/**
* @author 嘿嘿嘿1212
* @version 1.0
* @date 2020/2/21 19:17
*/
public class Singleton {
//懒汉式
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
通过if判断是否实例是否创建,从而进行实例化对象
存在问题
在并发环境下存在俩个线程同时进入if的情况,此时就有可能被获取到不同的实例对象的可能.
双重锁模式
是对上面的一种优化,同样可以达到延迟初始化作用.并且是线程安全的.该方法采用双锁机制,并且在多线程情况下能保持高性能
示例代码:
/**
* @author 嘿嘿嘿1212
* @version 1.0
* @date 2020/2/21 19:17
*/
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
作用:
外层if主要是为了提高效率,能够减少synchronized代码块的执行次数
而内层if是为了确定进入了代码块的线程,此时instance是没有实例对象的
synchronized代码块是为了防止同时有多个线程进入代码块