关于单例模式

关于单例模式

单例模式的种类

常见的有懒汉式和饿汉式两种,这两种模式懒汉和饿汉指的是何时在堆内存中为实例开辟内存空间而不是说通过什么形式或数据结构来创建和声明对象。如果是
在声明对象的时候直接实例化分配内存空间了这种是饿汉式,无论是通过static{}静态代码块还是通过static静态属性,都是在类加载阶段中的准备阶段去创建的。
对应的懒汉式对象的实例化分配内存空间无论是通过静态内部类还是通过加锁双重验证还是通过静态内部类,都是在获取具体实例的时候进行内存空间分配。下面是实现:

懒汉式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 懒汉式
* Created by xiehui1956(@)gmail.com on 2020/3/6
*/
public class SingleLazy {

private SingleLazy() {}

private static class Singleton {
public static SingleLazy singleLazy = new SingleLazy();
}

public static SingleLazy getInstance() {
return Singleton.singleLazy;
}
}
饿汉式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* 饿汉
* Created by xiehui1956(@)gmail.com on 2020/3/11
*/
public class SingleHu {

private SingleHu(){}

private static SingleHu singleHu = new SingleHu();

public static SingleHu getInstance(){
return singleHu;
}
}

单例模式是百分百安全的吗?有没有百分百安全的单例?

单例模式不是百分百安全的,没有百分百安全的单例。写单例的时候第一步就是私有化构造行数来禁止外部创建,但是就算私有化构造函数一样没办法保证单例不会被外部创建。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* Created by xiehui1956(@)gmail.com on 2020/3/11
*/
public class MyClass {

public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
SingleHu singleHu = SingleHu.getInstance();

Constructor<? extends SingleHu> constructor = singleHu.getClass().getDeclaredConstructor();
constructor.setAccessible(true);
SingleHu hu = constructor.newInstance();
System.out.println(singleHu);
System.out.println(hu);

}
}

运行结果:

1
2
model.SingleHu@3d82c5f3
model.SingleHu@2b05039f

以上,单例通过构造函数暴力反射也是可以获取对象的。所以也不能通过私有化构造方法来保证百分百不被破坏。如果错误,欢迎指正。感谢😊