SimpleDateFormat 你使用了吗?

本文深入探讨了Java中SimpleDateFormat类的线程安全性问题,指出其并非线程安全,并引用了JDK源码及Sun官方文档进行详细解析。提醒开发者在多线程环境下使用SimpleDateFormat时需注意同步问题。

SimpleDateFormat 你用了吗?

 

突然感觉有必要写一些日志了,很多知识点不温习就忘了,但是我今天不是忘了,是得到了一个新的教训。

项目上线了,出现了很多BUG,没办法只能一个一个的解决。本以为不会出现错误的方法确让我栽了个跟头,悲哀谈不上,单是有必要记录一下给自己个教训。

 

SimpleDateFormat 这个类估计写JAVA程序的都用过,但是真的都了解吗,我看不一定,和我一样只知道用不去了解的人还是有很多的,对此我希望能简单的提醒大家一下,这个类不是线程安全的(以前没有想到过这个问题!!!)。

 

SimpleDateFormat的Jdk 的Source,有这么一段注释,说明它不是线程安全的。
 Date formats are not synchronized.
 * It is recommended to create separate format instances for each thread.
 * If multiple threads access a format concurrently, it must be synchronized
 
再看一下Sun自己的网站上。在sun的bug database中
 Bug ID:  4228335  讲的就是这个问题。
 SimpleDateFormat is not threadsafe (one more try)
 其中有这么几段话值得关注:
 1、 Aside from the obvious, there are two reasons why this fix should be made:
- The documentation for DateFormat states that a DateFormat object should be used
multiple times, implying that construction is expensive.  Furthermore,
 no mention is made of SimpleDateFormat's lack of thread-safety. 
 Since for most applications the date formats remain constant,
 it is very easy to conclude that DateFormats should be application globals.
 But SimpleDateFormat produces incorrect results when used in this way.
- Bug 4101500, a similar problem with NumberFormat, was fixed.

建议修改这个问题,而且NumberFormat已经修改,解决了这个问题。

 

2、Use of a cloned Calendar object in format(), as suggested in JDC comments,
slows down the execution 30-50%. And it potentially affects footprint because
of cloned objects. Another approach would be to have a Calendar instance per
thread. However, this approach will cause problems at the API semantic level due
to the get/setCalendar methods.
这一段解释了为什么没修改这个问题,一个是保持API不变,另一个是因为Clone比new慢,会损失效率

具体 clone 和 new 这两个哪个效率更高一些,自己动手去网上查一下吧!此类的文章页很多!

是的,**如果是字符串类型(`String`)表示日期时间格式的数据**,你可以使用 `SimpleDateFormat` 类来进行解析和转换为 `Date` 类型。这是 Java 中处理日期字符串的一种传统方式(适用于 Java 8 及更早版本)。在 Java 8 及以上推荐使用 `java.time` 包中的类(如 `DateTimeFormatter` 和 `LocalDate` / `LocalDateTime`),但 `SimpleDateFormat` 仍然广泛存在并使用。 --- ## ✅ 示例:使用 `SimpleDateFormat` 将字符串转为 `Date` ```java import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class Main { public static void main(String[] args) { String dateStr = "2025-04-05 15:30:00"; // 定义日期格式,注意与字符串格式一致 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { // 将字符串解析为 Date 对象 Date date = sdf.parse(dateStr); System.out.println("解析后的 Date 对象: " + date); // 如果需要,也可以将 Date 再格式化回字符串 String formatted = sdf.format(date); System.out.println("再格式化回字符串: " + formatted); } catch (ParseException e) { System.err.println("日期格式解析失败:" + e.getMessage()); } } } ``` --- ## 🔍 代码解释: - `SimpleDateFormat("yyyy-MM-dd HH:mm:ss")`: - 构造一个日期格式模板,用于匹配输入字符串。 - 必须保证输入字符串的格式与模板一致,否则会抛出 `ParseException`。 - `sdf.parse(dateStr)`: - 将字符串解析成 `Date` 对象。 - `sdf.format(date)`: - 将 `Date` 对象格式化为字符串。 --- ## ⚠️ 注意事项 | 项目 | 说明 | |------|------| | **线程安全问题** | `SimpleDateFormat` 不是线程安全的,多线程环境下建议使用 `ThreadLocal` 或改用 `DateTimeFormatter` | | **异常处理** | 使用 `parse()` 方法时必须捕获 `ParseException` | | **Java 版本兼容性** | 适用于所有 Java 版本,但在 Java 8+ 推荐使用 `java.time.format.DateTimeFormatter` | --- ## ✅ Java 8+ 推荐方式:使用 `DateTimeFormatter` 和 `LocalDateTime` ```java import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class Main { public static void main(String[] args) { String dateStr = "2025-04-05 15:30:00"; DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); LocalDateTime dateTime = LocalDateTime.parse(dateStr, formatter); System.out.println("LocalDateTime: " + dateTime); String formatted = dateTime.format(formatter); System.out.println("格式化回字符串: " + formatted); } } ``` > ✅ 更现代、线程安全、功能更强,推荐在 Java 8 及以上使用。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值