`
Rainbow702
  • 浏览: 1076755 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类

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对象即可。

 

以上出自: http://www.cnblogs.com/hyddd/articles/1643978.html

 

但我认为还有一个办法可行,就是使用 ThreadLocal ,为每个线程保存该变量的一个副本,这样在各个线程中使用该 SimpleDateFormat 时,就不会与其他线程中的 SimpleDateFormat  变量发生冲突

分享到:
评论

相关推荐

    由浅入深解析 SimpleDateFormat

    在使用 SimpleDateFormat 时,需要注意以下几点: 1. SimpleDateFormat 是线程不安全的,因此在多线程环境下使用需要特别注意。 2. 创建 SimpleDateFormat 实例需要消耗大量的资源,因此应当尽量少创建实例。 3. ...

    有关SimpleDateFormat的常用方法说明

    - 在使用`SimpleDateFormat`时,需要注意日期和时间的格式是否符合预期,特别是在国际化应用中,不同的地区可能会有不同的日期和时间格式习惯。 - `SimpleDateFormat`是线程不安全的,如果在多线程环境中使用,需要...

    java SimpleDateFormat &Calendar

    需要注意的是,由于`SimpleDateFormat`不是线程安全的,所以在多线程环境中,建议为每个线程创建单独的实例。 `Calendar`类则是Java中更底层的日期和时间工具,它提供了一套完整的API来操作日期和时间,包括添加、...

    Java中的SimpleDateFormat使用详解

    在本文中,我们将深入探讨`SimpleDateFormat`的使用和相关知识点。 `SimpleDateFormat`的基本使用方法是创建一个新的实例,并通过传递一个字符串模式来设定日期和时间的格式。这个模式字符串由一系列特定的字母和...

    ThreadLocal:如何优雅的解决SimpleDateFormat多线程安全问题

    目录SimpleDateFormat诡异bug复现SimpleDateFormat诡异bug字符串日期转Date日期(parse)Date日期转String类型(format)SimpleDateFormat出现bug...ThreadLocal注意事项使用ThreadLocal解决SimpleDateFormat线程安全问题总结...

    JAVA使用SimpleDateFormat类表示时间代码实例

    需要注意的是,在使用 SimpleDateFormat 对象的 parse() 方法时可能会出现转换异常,即 ParseException,因此需要进行异常处理。 JAVA 中的日期和时间处理可以使用 Date 类和 SimpleDateFormat 类来实现,通过 ...

    java日期格式化SimpleDateFormat的使用详解

    java 日期格式化 SimpleDateFormat 的使用详解 java 中的日期格式化是通过 ...需要注意的是,在使用 SimpleDateFormat 时,需要注意日期和时间模式字符串的大小写,因为不同的模式字母具有不同的含义。

    日期格式转换的Java实现

    这涉及到的核心知识点包括:`DateFormat`类的基本使用、`SimpleDateFormat`类的具体应用、异常处理机制以及输入读取方式。 #### 1. `DateFormat`类简介 `java.text.DateFormat`是Java中用于以特定于语言环境的方式...

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

    在Java编程中,`SimpleDateFormat`是用于日期和时间格式化的关键类,但它存在一些需要注意的线程安全性问题。在本文中,我们将深入探讨`SimpleDateFormat`的工作原理,以及如何在多线程环境下正确使用它。 `...

    Java中SimpleDateFormat日期格式转换详解及代码示例

    在上面的代码示例中,我们使用了SimpleDateFormat将日期类型时间转换为字符串类型时间,并将字符串类型时间转换回日期类型时间。同时,我们也演示了如何使用SimpleDateFormat的常用格式定义来实现日期格式转换。 ...

    Java中SimpleDateFormat用法详解

    需要注意的是,`SimpleDateFormat`不是线程安全的,所以在多线程环境中,如果多个线程同时使用一个`SimpleDateFormat`实例,可能会出现错误。为了避免这个问题,可以在每个线程内部创建单独的实例,或者使用`...

    第五章.常用类.java.API概述——Date类,Calendar类,SimpleDateFormat类,Big.pdf

    需要注意的是,SimpleDateFormat不是线程安全的,所以在多线程环境下,应为每个线程创建单独的实例。 总结来说,这三个类在处理日期和时间时各有特点。Date类是最基础的,而Calendar类提供了更丰富的操作,...

    SimpleDateFormate格式说明.txt

    1. **格式化与解析**:`SimpleDateFormat`提供了一种方便的方式来格式化和解析日期,但需要注意的是,它不是线程安全的,如果在多线程环境中使用,应该考虑使用线程安全的`DateTimeFormatter`类。 2. **国际化问题**...

    java代码-SimpleDateFormat YYYY解析问题

    在处理日期时间问题时,还应注意以下几点: 1. 日期格式化类的线程安全问题:`SimpleDateFormat` 不是线程安全的,因此在多线程环境中,建议为每个线程创建单独的实例,或者使用 `java.time.format....

    JAVA获取当前时间并转换成string格式

    需要注意的是,SimpleDateFormat 的格式字符串 "yyyy/MM/dd HH:mm:ss" 可以根据需要进行修改。例如,如果我们想将日期和时间格式化为 "yyyy年MM月dd日 HH:mm:ss",那么我们可以将格式字符串修改为 "yyyy年MM月dd日 ...

    JAVA生成订单号(日期+流水号)

    - 使用`SimpleDateFormat`可以灵活地设置不同的格式,如仅使用日期部分 `"YYYYMMdd"` 或者更复杂的格式 `"YYYY-MM-dd HH:mm:ss"` 等。 2. **获取当前时间**:通过`new Date()`创建当前日期对象,并使用`...

    Java时间转换大全

    - **注意点**:使用`SimpleDateFormat`进行格式化。 ##### 5. 将当前时间转化为字符串(短格式) ```java /** * 获取当前时间,返回短时间字符串格式(yyyy-MM-dd) * * @return 返回字符串格式的时间 */ ...

    Java日期格式化及其使用例子收集

    本文将详细介绍`SimpleDateFormat`类的基本用法及应用场景,并通过具体的示例代码帮助读者更好地理解和掌握其使用技巧。 #### 二、`SimpleDateFormat`概述 `SimpleDateFormat`是Java中的一个用于日期格式化与解析的...

    用我工作经历总结的java常用方法和注意的问题

    - 使用 `SimpleDateFormat` 格式化日期,如 `"yyyy-mm-dd"`。通过 `Calendar` 对象进行日期计算。例如: ```java SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd"); long time = System....

    时间日期转换

    - 在使用 `SimpleDateFormat` 进行日期格式化或解析时,需要确保所使用的日期格式字符串是正确的,否则会抛出异常。 - 如果需要处理多种不同的日期格式,可以通过创建多个 `SimpleDateFormat` 实例来实现。 - 在处理...

Global site tag (gtag.js) - Google Analytics