面试过程中,单例模式总是会被问及,所以抽时间总结了一份单例相关的笔记
单例概念
单例模式是一种对象的创建模式,它用于产生一个对象的具体实例,它可以确保系统中一个类只产生一个实例
单例优点
对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些重量级对象而言,是非常可观的一笔系统开销,由于new操作的次数减少,因而对系统内存的使用频率也厚降低,这将降低GC压力,缩短GC停顿时间
单例的6种写法
- 饿汉式:无法对instance实例做延迟加载
- 懒汉式:多线程并发的情况下无法保证实例的唯一性
- 懒汉式线程安全:使用synchronized导致性能缺陷
- DCL:JVM即时编译器的指令重排序
- 静态内部类:延迟加载 / 线程安全 / 性能优势
- 枚举:在Java5之后才会出现,写法简单,线程安全
单例书写步骤
- 构造方法私有化,保证在类的外部无法实例化该类的对象
- 定义静态私有对象
- 定义对外开放的静态方法,在调用方法时判断对象是否为空,为空再创建对象返回
1.饿汉式:类加载的时候就实例化该类的对象
public class Singleton {
private Singleton(){}
private static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
2.懒汉式
public class Singleton {
private Singleton{}
private static Singleton instance;
public static Singleton getInstance(){
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
3.懒汉式线程安全
public class Singleton{
private Singleton{}
private static Singleton instance;
// 方法一:方法中声明synchronized关键字
public static synchronized Singleton getInstance(){
if (instance == null) {
instance = new Singleton();
}
return instance;
}
// 方法二:同步代码块中实现
public static Singleton getInstance(){
synchronized(Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
return instance;
}
}
4.DCL
public class Singleton {
private Singleton(){}
//volatile修饰的变量不允许线程内部缓存和重排序,即直接修改内存。
private static volatile Singleton instance;
public static Singleton getInstance(){
// 避免不必要的同步
if(instance == null){
synchronized(Singleton.class){
// 在第一次调用事初始化
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
5.静态内部类
public class Singleton{
private Singleton(){}
public static Singleton getInstance(){
return LazyHolder.instance;
}
private static class LazyHolder {
private static final Singleton instance = new Singleton();
}
}
6.枚举
public enum EnumSingleton{
// 定义一个枚举元素,它就是Singleton的一个实例
INSTANCE;
public void doSomething(){
}
}
网友评论