当被问到单例模式的时候,需要掌握以下几点:
1.单例模式定义及应用场景
单例模式是一种创建型设计模式,用于确保某个类只有一个实例,且该实例提供了全局访问点。该模式常用于线程池、日志、缓存、配置文件等需要只有一个实例的对象。
2.单例模式的实现方法
- 饿汉式
在类加载的时候就将单例对象创建好,因此不存在线程安全问题,但是会浪费一定的内存空间。
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return instance;
}
}
- 懒汉式
在需要使用单例对象时才创建,在多线程情况下可能会存在线程不安全问题,例如线程 A 和线程 B 同时尝试获取单例对象,A 获取到锁初始化单例之后,B 可能会再次进入 if 语句中,从而创建出新的实例。
public class Singleton {
private static Singleton instance = null;
private Singleton(){}
public static Singleton getInstance(){
if (instance == null){
instance = new Singleton();
}
return instance;
}
}
- 双重校验锁
通过双重判断,保证线程安全,同时提高了效率。
public class Singleton {
private static volatile Singleton instance = null;
private Singleton(){}
public static Singleton getInstance(){
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
3.单例模式的线程安全性问题
- 线程不安全
在多线程场景下,单例模式的实现可能会存在线程安全问题。
public class Singleton {
private static Singleton instance = null;
private Singleton(){}
public static Singleton getInstance(){
if (instance == null){
instance = new Singleton();
}
return instance;
}
}
- 线程安全
使用volatile和synchronized等关键字可以保证单例模式的线程安全。
public class Singleton {
private static volatile Singleton instance = null;
private Singleton(){}
public static Singleton getInstance(){
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
示例说明
示例1:懒汉式线程不安全示例
public class SingletonDemo {
public static void main(String[] args) {
Runnable runnable = () -> {
Singleton singleton = Singleton.getInstance();
System.out.println(singleton.hashCode());
};
Thread thread1 = new Thread(runnable, "Thread-1");
Thread thread2 = new Thread(runnable, "Thread-2");
thread1.start();
thread2.start();
}
}
示例输出:
217227986
1842773630
示例2:双重校验锁线程安全示例
public class SingletonDemo {
public static void main(String[] args) {
Runnable runnable = () -> {
Singleton singleton = Singleton.getInstance();
System.out.println(singleton.hashCode());
};
Thread thread1 = new Thread(runnable, "Thread-1");
Thread thread2 = new Thread(runnable, "Thread-2");
thread1.start();
thread2.start();
}
}
示例输出:
168044823
168044823
以上两个示例展示了懒汉式和双重校验锁两种单例模式的实现方式及其线程安全性问题。同时还介绍了单例模式的定义及应用场景。在面试中,可以根据面试官的问题来展开讨论,并举一些实际项目中的应用场景来巩固知识。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:教你java面试时如何聊单例模式 - Python技术站