日常开发中,我们经常使用
SimpleDateFormat
来对时间进行格式化/转换等操作。我们可以放心得使用在单线程环境中,但是需要时刻谨记SimpleDateFormat
是非线程安全的,在 Spark 开发中同样需要注意。尤其碰到时间相关数据的处理时,不管是 UDF 还是 匿名函数 ,都需要谨慎使用非线程安全的SimpleDateFormat
。
在这里和大家分享笔者如何在 Spark 开发中安全的使用 SimpleDateFormat
:
- 以下方案仅在使用 JDK 7及以下 的情况中推荐,如果使用 JDK 8及以上 ,请优先使用线程安全且性能更好的
DateTimeFormatter
来处理时间和日期 (性能测试参考链接);- 以下演示代码为
Scala
版本,Java
版本可自行修改;
- 声明线程安全的
ThreadSafeFormat
对象(也可以在类/对象中声明为变量)并覆写initialValue()
方法来设置初始值;import java.text.SimpleDateFormat import java.util.SimpleTimeZone /** * Thread Safe SimpleDateFormat for Spark. */ object ThreadSafeFormat extends ThreadLocal[SimpleDateFormat] { override def initialValue(): SimpleDateFormat = { val dateFormat = new SimpleDateFormat("yyyy-MM-dd:H") // 假如需要使用特定的时区,也可以指定 val utcTimeZone = new SimpleTimeZone(SimpleTimeZone.UTC_TIME, "UTC") dateFormat.setTimeZone(utcTimeZone) dateFormat } }
- 使用
ThreadSafeFormat.get()
就可以获取到线程安全的SimpleDateFormat
对象来处理日期和时间相关数据;
希望能帮到大家,如果大家有别的更好的选择,欢迎交流~