在使用SimpleDateFormat的经常会有一些错误的用法,例如如下方式:
public class TestDateFormat{
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
public void method1(){
sdf.format(new Date());
}
public void method2(){
sdf.format(new Date());
}
) 为了渐少new 的次数而把SimpleDateFormat做成成员或者静态成员,但这样的做法是隐含着错误的,是不
安全的。如下给出证明:
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class TestDateFormat{
private SimpleDateFormat sdf ;
public static void main(String[] args) {
SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd");
Date date1 = new Date();
Date date2 = new Date(date1.getTime()+1000*60*60*24);
System.out.println(date1);
System.out.println(date2);
Thread thread1 = new Thread(new Thread1(sdf,date1));
thread1.start();
Thread thread2 = new Thread(new Thread2(sdf,date2));
thread2.start();
}
}
class Thread1 implements Runnable{
private SimpleDateFormat sdf;
private Date date;
public Thread1(SimpleDateFormat sdf,Date date){
this.sdf = sdf;
this.date = date;
}
public void run() {
for(;;){
String strDate = sdf.format(date);
if("2007-02-27".equals(strDate)){
System.err.println("Error: date1="+strDate);
System.exit(0);
}
}
}
}
class Thread2 implements Runnable{
private SimpleDateFormat sdf;
private Date date;
public Thread2(SimpleDateFormat sdf,Date date){
this.sdf = sdf;
this.date = date;
}
public void run() {
for(;;){
String strDate = sdf.format(date);
if("2007-02-26".equals(strDate)){
System.err.println("Error: date1="+strDate);
System.exit(0);
}
}
}
} 很快,基本几十次就会出现错误。错误原因:
因为SimpleDateFormat处理复杂,Jdk的实现中使用了成员变量来传递参数,这个就造成在多线程的时候
会出现错误。上边的程序证明了这个问题。
再看看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已经修改,解决了这个问题。简单测试了一下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的快慢,看这里http://www.blogjava.net/dreamstone/archive/2007/02/26/100761.html。
其它的还有好多,感兴趣的自己看看吧。
结论:每次使用它的时候现new,或者用一个同步函数把new好的包装起来使用吧。
分享到:
相关推荐
目录SimpleDateFormat诡异bug复现SimpleDateFormat诡异bug字符串日期转Date日期(parse)Date日期转String类型(format)SimpleDateFormat出现bug...ThreadLocal注意事项使用ThreadLocal解决SimpleDateFormat线程安全问题总结...
SimpleDateFormat 详解 SimpleDateFormat 是 Java 语言中...然而,在使用时需要注意线程安全和资源消耗问题。通过合理地使用 SimpleDateFormat,我们可以实现日期和时间的高效格式化和解析,提高程序的性能和可读性。
- `SimpleDateFormat`是线程不安全的,如果在多线程环境中使用,需要考虑同步问题。 - 日期和时间的格式化字符串要与实际情况对应,避免出现理解错误。 以上就是关于`SimpleDateFormat`的一些常见用法和注意事项,...
需要注意的是,由于`SimpleDateFormat`不是线程安全的,所以在多线程环境中,建议为每个线程创建单独的实例。 `Calendar`类则是Java中更底层的日期和时间工具,它提供了一套完整的API来操作日期和时间,包括添加、...
需要注意的是,在使用 SimpleDateFormat 对象的 parse() 方法时可能会出现转换异常,即 ParseException,因此需要进行异常处理。 JAVA 中的日期和时间处理可以使用 Date 类和 SimpleDateFormat 类来实现,通过 ...
需要注意的是,`SimpleDateFormat`不是线程安全的,因此在多线程环境中使用时,要么为每个线程创建独立的实例,要么使用`ThreadLocal`来存储实例。 此外,`SimpleDateFormat`也存在一些效率问题,因为它的解析过程...
java 日期格式化 SimpleDateFormat 的使用详解 java 中的日期格式化是通过 ...需要注意的是,在使用 SimpleDateFormat 时,需要注意日期和时间模式字符串的大小写,因为不同的模式字母具有不同的含义。
在标题和描述中提到的 "YYYY" 解析问题,通常指的是在使用 `SimpleDateFormat` 进行日期解析时遇到的困惑或错误。 首先,我们需要明确 `YYYY` 和 `yyyy` 在 `SimpleDateFormat` 中的区别。`yyyy` 是一个代表年份的...
在Java编程中,`SimpleDateFormat`是用于日期和时间格式化的关键类,但它存在一些需要注意的线程安全性问题。在本文中,我们将深入探讨`SimpleDateFormat`的工作原理,以及如何在多线程环境下正确使用它。 `...
但是,通常我们不直接使用`DateFormat`类,而是使用其子类`SimpleDateFormat`,因为它提供了更多的灵活性。 #### 2. `SimpleDateFormat`类详解 `SimpleDateFormat`是`DateFormat`的一个子类,它可以让我们根据...
在上面的代码示例中,我们使用了SimpleDateFormat将日期类型时间转换为字符串类型时间,并将字符串类型时间转换回日期类型时间。同时,我们也演示了如何使用SimpleDateFormat的常用格式定义来实现日期格式转换。 ...
需要注意的是,`SimpleDateFormat`不是线程安全的,所以在多线程环境中,如果多个线程同时使用一个`SimpleDateFormat`实例,可能会出现错误。为了避免这个问题,可以在每个线程内部创建单独的实例,或者使用`...
1. **格式化与解析**:`SimpleDateFormat`提供了一种方便的方式来格式化和解析日期,但需要注意的是,它不是线程安全的,如果在多线程环境中使用,应该考虑使用线程安全的`DateTimeFormatter`类。 2. **国际化问题**...
需要注意的是,SimpleDateFormat不是线程安全的,所以在多线程环境下,应为每个线程创建单独的实例。 总结来说,这三个类在处理日期和时间时各有特点。Date类是最基础的,而Calendar类提供了更丰富的操作,...
Java 中的 Date、String 和 Timestamp 之间的转换问题 Java 中的日期和时间处理是编程中非常重要的一方面,Date、String 和 ...Java 中的日期和时间处理需要注意不同类型之间的转换问题,以避免出现奇怪的结果。
需要注意的是,SimpleDateFormat 的格式字符串 "yyyy/MM/dd HH:mm:ss" 可以根据需要进行修改。例如,如果我们想将日期和时间格式化为 "yyyy年MM月dd日 HH:mm:ss",那么我们可以将格式字符串修改为 "yyyy年MM月dd日 ...
- 使用 `SimpleDateFormat` 格式化日期,如 `"yyyy-mm-dd"`。通过 `Calendar` 对象进行日期计算。例如: ```java SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd"); long time = System....
总结来说,`DateFormat`的线程安全性问题要求开发者在多线程环境中特别注意其使用方式。通过理解这些潜在风险,我们可以采用适当的策略,如使用`ThreadLocal`,每次都创建新实例,或者切换到更现代的日期时间API,以...
### JAVA生成订单号(日期+...需要注意的是,在实际应用中,为了更好地保证订单号的唯一性,可能还需要考虑并发控制等问题。例如,可以引入序列号管理机制或使用数据库自增字段等技术手段来进一步优化订单号生成流程。
2.为什么要求日期格式化时必须有使用y表示年,而不能用Y? 在Java中,我们经常需要对日期进行格式化。在日期格式化时,我们需要使用正确的格式符号,例如y表示年,M表示月,d表示日。但是,为什么我们不能使用Y表示...