设计模式八股
单例模式实现
懒汉式(线程不安全)
1 | public class Lazy { |
懒汉式是指先不创建实例,当首次调用后再创建。
私有化构造方法,不能使用 new 进行实例化,使用方法判断当前实例是否已存在,不存在则创建,保证实例的单一性。
线程不安全,在多线程情况下,可能首次会有多个线程一起调用 getLazyInstance方法 ,那么此时实例为空,会同时创建多个实例。
饿汉式(线程安全)
1 | public class Hungry { |
饿汉式指无论是否要使用实例,先进行一次实例化,随后需要实例时直接调用方法返回即可;
线程安全,因为初始化类时已经进行了实例化。但若长时间不使用该实例会造成资源浪费。
懒汉式(线程安全)
1 | public class LazyConcurrent { |
在实例化执行方法上加锁保证线程安全。
线程安全,但效率低,多线程争夺锁会造成线程阻塞。
双重检查锁实现(线程安全)
1 | public class DoubleCheck { |
双重检查锁相当于是线程安全懒汉式的优化版。
首先我们不是在执行方法上加锁,而是在方法内部加锁。先进行一次实例判断,如果为空则获得锁然后再进行一次判断,因为第一次判断可能有多个线程同时通过,而获取锁后需要第二次判断再实例对象,以防同时通过第一次判断线程进行多次实例化。
实例变量使用volatile修饰。我们正常代码实例化执行步骤如下:
1 | doubleCheckInstance = new DoubleCheck(); |
由于JVM的指令重排机制,指令执行顺序可能会由原来的123变为132。而在多线程的影响下,会导致线程得到一个尚未初始化的实例。为了解决该问题可以在声明实例变量时加上 volatile,禁止JVM进行指令重排,保证多线程的安全。
静态内部类实现(线程安全)
1 | public class Single { |
当外部类Single加载时,其静态内部类SingleInner并未加载,当调用实例获取方法走到返回值时,才会去加载静态内部类,并进行实例化。
使用静态内部类可以延迟实例化,节省资源,并保证线程安全。
枚举实现(线程安全)
1 | public enum Unique { |
枚举默认即线程安全 + 单例,还可防范一系列反射破解单例的操作。
设计模式七大原则
- 单一职责原则:一个类只负责一个功能,降低耦合性,方便迭代维护。
- 开放封闭原则:类、方法可以进行功能扩展,但不能修改。对扩展开放,对修改封闭。
- 依赖倒置原则:高级模块不能依赖低级模块,都应该依赖于接口。先将类进行抽象,先设计功能接口,再对接口进行功能细节的实现。
- 接口隔离原则:不同接口定义不同的功能。
- 里氏代换原则:子类可替换其父类。
- 迪米特原则:每个模块间要尽可能少的相互调用,减少依赖,降低耦合性。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 哀殿firstの空间!
评论