今天会是有Offer的一天么:面试时手写单例模式

非常常规的一道面试题,UP在字节实习二面的时候被问到了这个问题(话说字节真的非常看重算法能力,每一面都会至少手撕两道算法题目)。

在这里插入图片描述

接下来给出最常见的几种单例模式的实现

饿汉式—静态常量方式:

public class Singleton {  
    private static Singleton instance = new Singleton();  
    private Singleton (){}  
    public static Singleton getInstance() {  
    return instance;  
    }  
}

在类加载的时候就初始化了实例对象,因此在多线程的情况下是线程安全的。

饿汉式—静态代码块方式

public class Singleton {
    private static Singleton instance;
    static {
        instance = new Singleton();
    }
    private Singleton() {}
    public static Singleton getInstance() {
        return instance;
    }
}

将类的实例化放在了静态代码块中,保证只会初始化一次,同样线程安全。

懒汉式(线程不安全)

public class Singleton {
    private static Singleton instance;
    private Singleton() {}
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

多线程场景下禁止使用,因为可能会产生多个对象,线程不安全。

懒汉式(线程安全)

public class Singleton {
    private static Singleton instance;
    private Singleton() {}
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

在getInstance()方法上加了Synchronized关键字。保证了多线程情况下的线程安全。

写到这基本就介绍完了我们最常见的几种单例模式。

在这里插入图片描述

双重校验锁(线程安全,非常重要)

public class Singleton {
	private volatile static Singleton instance;
	private Singleton() {}
	public static Singleton getSingleton() {
		if (instance == null) {
			synchronized (Singleton.class) {
				if (instance == null) {
						instance = new Singleton();
				}
			}
		}
		return instance;
	}
}

这种情况下双重校验,首先判断instance是否为null,不用每次都获取锁,减少了获取锁的次数,效率比较高。
有一点格外要注意,volatile关键字的使用。为什么要用volatile关键字进行修饰,因为我们知道volatile关键字可以保证禁止指令重排。对于instance = new Singleton()这行代码它可以分解为三个步骤:
1 分配内存
2 初始化对象
3 将instance指向刚刚分配的地址
如果不使用volatile关键字进行修饰,可能会出现重排序,例如从1-2-3 排序为1-3-2。假如此时有2个线程A,B。线程A在执行instance = new Singleton()这行代码时,B线程进来,而此时A执行完了1和3,没有执行2,此时B线程判断instance不为null 直接返回一个未初始化的对象,就会出现问题。
在这里插入图片描述

掌握这几种单例模式的实现,基本就可以应对单例模式的面试题了。

发布了4 篇原创文章 · 获赞 3 · 访问量 2473

猜你喜欢

转载自blog.csdn.net/HZGuilty/article/details/105557203
今日推荐