`

Findbug提示SimpleDateFormat出现多线程安全问题

    博客分类:
  • Java
阅读更多
Bug: Call to method of static java.text.DateFormat
Pattern id: STCAL_INVOKE_ON_STATIC_DATE_FORMAT_INSTANCE, type: STCAL, category: MT_CORRECTNESS

As the JavaDoc states, DateFormats are inherently unsafe for multithreaded use. The detector has found a call to an instance of DateFormat that has been obtained via a static field. This looks suspicous.

For more information on this see Sun Bug #6231579 and Sun Bug #6178997.



    上面的英文解释其实应该说得比较清楚,在Java文档中,已经明确说明了DateFormats 是非线程安全的,而在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中,Sun Bug #6231579 ,Sun Bug #6178997都可以印证这个问题。

    导致SimpleDateFormat出现多线程安全问题的原因,是因为:SimpleDateFormat处理复杂,Jdk的实现中使用了成员变量来传递参数,这就造成在多线程的时候会出现错误。

    而Findbugs所说的“Call to static DateFormat”,其实就是一些人:为了渐少new 的次数而把SimpleDateFormat做成成员或者静态成员,上面已经说了,这样做是不安全的。

    其实,出现这种问题的代码一般都长得差不多,典型的代码示例如下:

public class Test{
     private SimpleDateFormat dateFormat  = new SimpleDateFormat("yyyy-MM-dd");
     public void method1(){
         dateFormat.format(new Date());
     }
     public void method2(){
         dateFormat.format(new Date());
     }
)



再给个详细例子说明问题,看下面代码:
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class Test{
    private SimpleDateFormat dateFormat ;
    public static void main(String[] args) {
        SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd");
        Date today = new Date();
        Date tomorrow = new Date(today.getTime()+1000*60*60*24);
        System.out.println(today); // 今天是2010-01-11
        System.out.println(tomorrow); // 明天是2010-01-11
        Thread thread1 = new Thread(new Thread1(dateFormat,today));
        thread1.start();
        Thread thread2 = new Thread(new Thread2(dateFormat,tomorrow));
        thread2.start();
    }
    
}
class Thread1 implements Runnable{
    private SimpleDateFormat dateFormat;
    private Date date;
    public Thread1(SimpleDateFormat dateFormat,Date date){
        this.dateFormat = dateFormat;
        this.date = date;
    }
    public void run() {
        for(;;){// 一直循环到出问题为止吧。
            String strDate = dateFormat.format(date);
            // 如果不等于2010-01-11,证明出现线程安全问题了!!!!
            if(!"2010-01-11".equals(strDate)){
                System.err.println("today="+strDate);
                System.exit(0);
            }
        }
    }
}
class Thread2 implements Runnable{
    private SimpleDateFormat dateFormat;
    private Date date;
    public Thread2(SimpleDateFormat dateFormat,Date date){
        this.dateFormat = dateFormat;
        this.date = date;
    }
    public void run() {
        for(;;){
            String strDate = dateFormat.format(date);
            if(!"2010-01-12".equals(strDate)){
                System.err.println("tomorrow="+strDate);
                System.exit(0);
            }
        }
    }
}

运行的结果如下:

Mon Jan 11 11:30:36 CST 2010
Tue Jan 12 11:30:36 CST 2010
tomorrow=2010-01-11

终于看到问题了,tomorrow=2010-01-11,错得很明显了。其实要避免这个问题方法很简单,不使用SimpleDateFormat,或者不使用成员变量/静态成员变量的SimpleDateFormat对象即可。
分享到:
评论

相关推荐

    findbug3下载

    1. **实时反馈**:在编写代码的同时,FindBug3会即时检查新添加的代码行,提示可能存在的问题。 2. **集成开发环境**:与MyEclipse的紧密集成使得错误提示直接显示在代码编辑器中,便于快速定位和修复。 3. **代码...

    eclipse 3 findbug 插件

    eclipse,findbug, 插件,找錯eclipse,findbug, 插件,找錯eclipse,findbug, 插件,找錯eclipse,findbug, 插件,找錯eclipse,findbug, 插件,找錯

    findbug 错误日志文档

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

    findbug2.0版本

    安装成功后,可以在IDE中对项目进行分析,FindBug会生成一个报告,列出所有检测到的问题,包括错误的严重程度、错误类型以及可能的解决方案。这对于团队开发尤其有用,因为它可以确保代码在提交前达到一定的质量标准...

    静态代码分析工具 findbug

    4. **并发问题(Concurrency issues)**:如线程不安全的类、死锁、竞态条件等,FindBugs能够识别这些可能导致多线程程序不稳定的问题。 5. **不安全的类型转换(Unsafe cast)**:当强制类型转换可能会失败时,...

    静态代码检查插件之findbug

    此外,它还能检测到线程不安全的代码和可能导致内存泄漏的模式。 在【描述】中提到的空指针错误是Java编程中常见的问题,可能导致程序崩溃。FindBugs对此有特别的关注,它能够检测出可能导致NPE(Null Pointer ...

    findbug1.3.9

    这个经典的插件就不用多说了,当然还有checkstyle。让我们的代码更漂亮吧。 插件安装时,我们只需在eclipse根目录下新建一个【links】目录,然后在里面创建【.link】扩展名的文件,在里面写上类似于【path=F:\\IDE\\...

    Findbug-eclipse插件安装及使用说明

    这些错误包括空指针异常、未初始化的变量、内存泄漏、线程安全问题等。FindBugs不仅仅是一个简单的错误检测器,它还提供了很多关于如何优化代码的建议,从而提升代码质量和可读性。 **二、安装FindBugs Eclipse插件...

    FindBug检查问题指南.docx

    《FindBug检查问题指南》 FindBugs是一款静态分析工具,用于检测Java代码中的潜在错误和不良编程习惯。本指南将深入探讨FindBugs在实际使用中遇到的一些常见问题,并提供解决方案。 首先,我们来看一个关于`String...

    eclipse findbug插件

    3. 不安全的线程操作:找出可能的并发问题,如未同步的访问共享资源。 4. 数组越界:检测出可能的数组越界访问,防止程序崩溃。 5. 漏洞和安全问题:识别可能的安全漏洞,如不安全的网络通信或敏感数据处理。 6. 死...

    findbug代码走查过滤注释类

    将类引入项目,在不想用findbug检查的代码类或方法上,添加该注释

    findbug 常见异常处理

    Multithreaded correctness: 多线程正确性 Performance:性能 Security:安全 Dodgy: 欺骗性代码 2、 常见Bug以及处理办法 a) 不需要处理 May expose internal representation by incorporating reference to mutable...

    findBug eclipse

    FindBugs插件提供了丰富的错误分类,包括设计问题、多线程问题、空指针异常、资源泄漏等。它能够检测出许多常见的编程错误,如未初始化的变量、潜在的空指针异常、不必要的对象创建、可能的数组越界等。通过这些提示...

    findbug插件自动排查简单bug.rar

    通过集成到开发环境(如Eclipse、IntelliJ IDEA等)中,FindBugs可以在编码阶段实时地对新添加的代码进行分析,并在问题出现时立即通知开发者。这种即时反馈有助于开发者快速定位和修复问题,避免了传统方式下在后期...

    findBug 程序测试使用

    发现程序中的bug,此html对此用stanford的软件进行介绍分析

    FindBug的安装与应用(Eclipse 、MyEclipse)

    **FindBug的安装与应用(Eclipse、MyEclipse)** FindBugs是一款强大的静态代码分析工具,用于检测Java代码中的潜在错误和不良编程习惯。它通过分析字节码而非源代码,可以在编码阶段提前发现潜在的bug,提高软件质量...

    Findbug使用指南.docx

    Findbug 使用指南 Findbug 是一个开源的 Eclipse 代码检查工具,能够简单高效全面地帮助我们发现程序代码中存在的 bug、bad smell 以及潜在隐患。它提供了简单的修改意见供我们重构时进行参考,通过使用它,可以...

    java代码质量检测工具包含findbug、pmd插件等

    它提供了一套详细的错误等级分类,从最严重的错误到可能的改进,帮助开发者优先处理最紧迫的问题。FindBugs还支持自定义规则,以便适应特定的项目需求。集成到MyEclipse这样的IDE中,可以在编码时实时给出反馈,提高...

Global site tag (gtag.js) - Google Analytics