接上篇:https://developer.aliyun.com/article/1228152?spm=a2c6h.13148508.setting.25.21084f0eNCKPti
三、 使用ThreadLocal存储线程专有对象
ThreadLocal提供了线程专有对象,可以在整个线程生命周期中随时取用,极大地方便了一些逻辑的实现。
常见的ThreadLocal用法主要有两种:
• 保存线程上下文对象,避免多层级参数传递;
• 保存非线程安全对象,避免多线程并发调用。
1. 保存线程上下文对象,避免多层级参数传递
这里,以PageHelper插件的源代码中的分页参数设置与使用为例说明。
1) 设置分页参数代码
2) 使用分页参数代码
3) 使用分页插件代码
如果要把分页参数通过函数参数逐级传给查询语句,除非修改MyBatis相关接口函数,否则是不可能实现的。
2. 保存非线程安全对象,避免多线程并发调用
在写日期格式化工具函数时,首先想到的写法如下:
其中,每次调用都要初始化DateFormat导致性能较低,把DateFormat定义成常量后的写法如下:
由于SimpleDateFormat是非线程安全的,当多线程同时调用formatDate函数时,会导致返回结果与预期不一致。如果采用ThreadLocal定义线程专有对象,优化后的代码如下:
这是在没有线程安全的日期格式化工具类之前的实现方法。在JDK8以后,建议使用DateTimeFormatter代替SimpleDateFormat,因为SimpleDateFormat是线程不安全的,而DateTimeFormatter是线程安全的。当然,也可以采用第三方提供的线程安全日期格式化函数,比如apache的DateFormatUtils工具类。
注意:
ThreadLocal有一定的内存泄露的风险,尽量在业务代码结束前调用remove函数进行数据清除。
接下篇:https://developer.aliyun.com/article/1228148?groupCode=java