单例模式
自己简单整理的笔记,个人认为单例模式没必要所有写法全部了解,选择自己了解的比较全面的,足以应对面试。
懒汉模式
private static singletonClass instance;
private singletonClass(){}
public static singletonClass getInstance(){
if(instance == null){
instance = new singletonClass();
}
return instance;
}
懒汉模式,顾名思义当程序第一次调用的时候会去创建该对象,单线程模式下对象唯一,多线程模式下不能保证线程安全
示例:
public class ListTest {
public static void main(String[] args) {
multiThreadSingleton1();
}
/**
* 多线程情况下懒汉实现导致的问题
*/
public static void multiThreadSingleton1(){
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
singletonClass second = singletonClass.getInstance();
System.out.println(second);
}
});
thread.start();
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
singletonClass one = singletonClass.getInstance();
System.out.println(one);
}
});
thread2.start();
}
}
拿到的是两个不一样的对象,所以多线程模式先,常规的懒汉模式是不安全的
饿汉模式
private static final singletonClass instance = new singletonClass();
private singletonClass(){}
public static singletonClass getInstance(){
return instance;
}
饿汉模式,就是在类初始化的时候就是new 这个对象,所以无论单线程还是多线程拿到的都是相同的对象,是线程安全的。
懒汉模式变种,加入锁
private static singletonClass instance;
private singletonClass(){}
public static singletonClass getInstance(){
synchronized (singletonClass.class){
if(instance == null){
instance = new singletonClass();
}
}
return instance;
}
对懒汉模式进行加锁处理,多个线程请求过来执行同步方法,当第一个线程new 完对象之后,后续线程不会在执行初始化操作,拿到的都是同一个对象
静态内部类
private static class singletonClassHolder{
private static final singletonClass SINGLETON_CLASS = new singletonClass();
}
private singletonClass(){}
public static singletonClass getInstance(){
return singletonClassHolder.SINGLETON_CLASS;
}
静态内部类算是饿汉模式变种,是一种比较推崇的方式,整个类初始化的时候不会去加载 SINGLETON_CLASS,对象,当有别的类调用的时候,才会初始化内部类中的对象。相较于饿汉模式有点在于,如果该类占用资源较大,后续又很长时间不用,就是导致资源浪费,静态内部类只有在调用的时候才会初始化,需要的时候才会new这个对象。