「这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战」
Java装饰器模式与线程特有对象
Java装饰器模式
顾名思义,装饰器模式可配置特定对象的功能。这是Java原始IO类中的一种常见模式,用于对JVM之外的源进行读写。例如,InputStream和OutputStream类及其子类在其读取和写入操作中广泛使用此模式。可以链接这些类的实现,以有效地从不同的源(例如本机文件系统)读取和写入数据。
使用装饰器模式的一个好处就是实现关注点分离,在这种设计中,实现同一组功能的对象的两个版本:非线程安全的对象与线程安全的对象. 对于非线程安全的在设计时只关注要实现的功能,对于线程安全的版本只关注线程安全性。
实际上Java提供的工具包中,IO相关工具就普遍大量使用了装饰器模式,例如充当装饰功能的IO类如BufferedInputStream等,又被称为高级流,通常将基本流作为高级流构造器的参数传入,将其作为高级流的一个关联对象,从而对其功能进行扩展和装饰。
装饰器模式(Decorator Pattern),动态地给一个对象添加一些额外的职责,就增加功能来说,装饰器模式比生成子类更灵活。 ----《大话设计模式》
装饰器模式由四个部分组成
- 抽象构件(Component):一个抽象类,包含一个抽象方法,被装饰类和装饰器类都需要继承这个抽象类
- 具体构件(ConcreteComponent):即被装饰类,需要重写抽象方法
- 抽象装饰(Decorator):一个继承了抽象构建的抽象类,作为具体装饰类的共同父类,该类不是必须的;含有一个全抽象构件的变量-未实例化,并在提供一个以被修饰类对象为入参的构造方法,在构造方法内部将该对象赋值给全局声明的抽象构建变量
- 具体装饰(ConcreteDecorator):一个继承了抽象装饰类的子类,重写抽象方法,一般在方法内部调用父类的同名方法,然后增加新的装饰逻辑
线程特有对象
我们可以选择不共享非线程安全的对象,对于非线程安全的对象,每个线程都创建一个该对象的实例,各个线程线程访问各自创建的实例,一个线程不能访问另外一个线程创建的实例. 这种各个线程创建各自的实例,一个实例只能被一个线程访问的对象就称为线程特有对象. 线程特有对象既保障了对非线程安全对象的访问的线程安全,又避免了锁的开销.线程特有对象也具有固有的线程安全性。
ThreadLocal类相当于线程访问其特有对象的代理,即各个线程通过ThreadLocal对象可以创建并访问各自的线程特有对象,泛型T指定了线程特有对象的类型. 一个线程可以使用不同的ThreadLocal实例来创建并访问不同的线程特有对象。
ThreadLocal实例为每个访问它的线程都关联了一个该线程特有的对象, ThreadLocal实例都有当前线程与特有实例之间的一个关联。