单例模式(Singleton)
单例模式(Singleton)

分为单例类(只能创建一个实例的类)和访问类(test)
—————————-华丽分隔符————————————
实现方式:
一 饿汉式 : 类加载时就会创建单实例对象造成一定的浪费
在类内部创建好该类的对象, 对外提供获取实例的方法
成员变量并赋值/静态代码块赋值

Enum—>有限集合
1 | public enum Singleton { |
1 | public void doSomething() { |
二 饱汉式 : 用类名.getInstance时才创建, 但是多线程会出现并发创建多个实例的问题
有两种方法解决: 1.volatile + double check+ synchronized 2.静态内部类
其中静态内部类:
原理:
要点
a. 静态内部类属于外部类本身,不依赖外部类实例
- 所以同一个外部类的多个实例共享同一个静态内部类。
b. 静态内部类的类加载和静态成员初始化是延迟的
- 只有第一次访问静态内部类时,JVM 才会加载类并初始化静态字段(懒加载)
- JVM 保证类加载和静态字段初始化的线程安全,因此单例实例只会创建一次,无需额外加锁。
—————————-华丽分隔符————————————
单例模式被破坏情形:
1.反序列化
原因:
- 反序列化时,JVM 会创建一个全新的对象,而不是调用你单例类的 getInstance() 方法
- 即使构造器是私有的,也无济于事
- 所以序列化破坏了单例模式 → 原来的单例可能被复制多次
2.反射
- 反射(Reflection)允许你访问类的 私有构造器
- 即使单例类把构造器 private,反射也能绕过访问控制:
解决方案:
1.加一个readObject()方法用以返回内部类定义的实例.
这样jvm会先看是否有readObject方法
2.enum
java中单例的例子:
Runtime