`
cunzhangok
  • 浏览: 66210 次
  • 性别: Icon_minigender_1
  • 来自: 江苏
社区版块
存档分类
最新评论

SimpleDateFormat 是非线程安全

 
阅读更多
在使用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
分享到:
评论

相关推荐

    深入理解Java:SimpleDateFormat安全的时间格式化

    这两个方法都是非线程安全的,因此需要使用同步代码来避免问题。 知识点8: SimpleDateFormat的应用场景 SimpleDateFormat类常用于日期字符串解析和格式化输出,例如在导出excel文件时,需要将日期对象转化为字符串...

    Java ThreadLocal 线程安全问题解决方案

    例如,`SimpleDateFormat` 是非线程安全的,因为它内部使用了一个`Calendar`对象,多个线程同时使用一个`SimpleDateFormat`实例进行解析或格式化日期时,可能会出现线程A操作未完成而线程B已经开始的问题,导致数据...

    findbug 错误日志文档

    findbug的错误日志文档... 上面的英文解释其实应该说得比较清楚,在Java文档中,已经明确说明了DateFormats 是非线程安全的,而在SimpleDateFormat的Jdk 的Source文件中,我们也找到这么一段注释,说明它不是线程安全的

    Java DateFormat并发实现

    `SimpleDateFormat`是`DateFormat`的一个具体实现,它也是非线程安全的。在并发情况下,可以使用同步块或者静态工厂方法来创建新的`SimpleDateFormat`实例,确保在每次需要格式化或解析日期时都创建新的对象。 ```...

    java开发岗位面试题汇总

    - **HashMap**:提供了更好的性能,是非线程安全的,允许使用`null`键和值。它没有同步控制,因此性能更高。 - **ConcurrentHashMap**:为了解决多线程环境下HashMap的安全问题,引入了此类。它使用了分段锁技术,...

    观看韩顺平Java的 所做的笔记 到互斥锁 其中里面有我很多心得 老手可以用来复习 新手可以用学习 也可以当做参考 来做笔记

    StringBuilder是非线程安全的,适合单线程环境,而StringBuffer是线程安全的,适用于多线程环境。 4. **Math类**: 提供了各种数学运算,如max()、min()、random()等,用于进行基本的数学计算。 5. **Arrays类**...

    常用代码:java日期处理

    - 使用时需要注意线程安全问题,因为它是非线程安全的,建议在多线程环境中使用局部变量或线程局部变量。 4. **Java 8的`java.time`包** - `LocalDate`: 表示没有时区的日期。 - `LocalTime`: 表示没有日期的...

    Java面试题汇总及答案

    在Java中,`SimpleDateFormat` 类是非线程安全的。这意味着,在多线程环境下直接复用一个`SimpleDateFormat`实例可能会导致数据错误或异常。 **3.2 解决方案** 1. **每次 new 一个新的对象**:这是最简单但不是最...

    Java期末复习-常用类库

    StringBuilder则是非线程安全但性能更高的替代选项。 Runtime类是Java运行时环境的接口,允许Java程序与操作系统进行交互。通过Runtime.getRuntime()获取单例实例,可以调用freeMemory()获取剩余内存,maxMemory()...

    Java开发手册(嵩山版)灵魂15问.pdf

    SimpleDateFormat定义为static变量可能导致线程安全问题,因为它是非线程安全的。在多线程环境中,多个线程同时使用同一个SimpleDateFormat实例可能会导致日期格式混乱。因此,应在需要时创建并使用,或者使用线程...

    java常用工具类

    - `java.lang.StringBuilder`和`java.lang.StringBuffer`:用于字符串拼接,`StringBuilder`是非线程安全的,而`StringBuffer`是线程安全的。 5. **Apache Commons Lang**: - Apache Commons Lang是Apache软件...

    javaSE_java_core.pdf

    `StringBuilder`是非线程安全的,适用于单线程环境,而`StringBuffer`是线程安全的,适用于多线程环境。`Date`类用来表示日期和时间,`SimpleDateFormat`则用于格式化和解析日期字符串。`Calendar`类是一个抽象类,...

    获取当前时间

    - 在高并发或多线程环境下使用 `DateFormat` 时,由于它是非线程安全的,需要通过同步机制来避免潜在的问题。例如,可以通过使用 `ThreadLocal` 来缓存每个线程的 `DateFormat` 实例。 4. **安全性问题**: - 当...

    Java常用Util类

    7. **StringBuilder和StringBuffer**: 都用于字符串拼接,StringBuilder是非线程安全的,效率较高;StringBuffer是线程安全的,适合多线程环境。 8. **Random**: 提供随机数生成,可以生成指定范围内的整数或浮点数...

    2011 广州 面试笔试题:.doc

    50. 什么是线程安全,如何实现线程安全? 面试和笔试题目涵盖了多个IT领域的知识点,包括流程管理(JBPM)、消息队列(JMS)、XML解析、多线程、网络协议、Java Web开发框架(Struts、Hibernate、Spring)、Spring...

    达内_jsd1410第一次月考题

    - `StringBuilder`是非线程安全的,而`StringBuffer`是线程安全的,所以在多线程环境中推荐使用`StringBuffer`。 2. **多态和方法重写**: - 类`B`继承自`A`,并重写了`f()`方法。在多态场景下,当`A`类型的引用...

    2019年最新版修订版Java程序员面试宝典.pdf

    - `HashMap`是非线程安全的,`HashTable`是线程安全的。 8. **数组与链表适用场景**: - 数组适用于频繁的随机访问,且大小固定的场景。 - 链表适用于频繁的插入删除操作,且大小不确定的场景。 9. **`...

    Java clock_javaclock_java_

    Swing组件通常是非阻塞的,这意味着它们可以在事件调度线程中安全地更新,这对于实时应用如时钟来说非常重要。 关键的类可能是`JFrame`,它是窗口的基础,以及`JLabel`或`JPanel`,用于显示时钟的数字。为了显示...

    100 Recipes for Programming Jav - Jamie Munro

    - **解释**: HashMap是非线程安全的,而Hashtable是线程安全的。此外,两者在处理null值的方式上也有所不同。例如,HashMap允许一个null键和多个null值,而Hashtable不允许任何null键或值。 ##### 食谱2: 如何将...

Global site tag (gtag.js) - Google Analytics