- 浏览: 379300 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
u014689192:
很不错
JMX学习笔记(三)-MXBean -
focus2008:
进制转换之后,根本不会执行js代码,感觉你没有测试过吧
xss漏洞之进制转换 -
focus2008:
如何使用过滤器来处理呢?
xss漏洞之进制转换 -
1169158401:
我艹,我那天这么写,包括一些方法,然后那货说这样写不容易看懂。 ...
import static简化代码 -
AquariusM:
奢华的JVM介绍!
JMX学习笔记(三)-MXBean
万能的SimpleDateFormat可以把java.util.Date对象, 或者类似 "2010-11-24 23:23:11.666"的
字符串转换成我们需要的格式或者时间对象。
但是由于时间的概念复杂,又牵扯到时区与本地化,导致了SimpleDateFormat需要处理太多的时间细节,
new一个SimpleDateFormat需要华为太多的时间,这样可能会想到缓存SimpleDateFormat对象
但是万能的SimpleDateFormat恰恰又不是现成安全的。
如果在单线程情况下,缓存SimpleDateFormat对象是不错的选择。
package com.haitao.utils; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public final class SimpleDateFormatUtils { public static final String DATE_PARTEN = "yyyy-MM-dd HH:mm:ss.SSS"; // 静态化缓存 private static SimpleDateFormat format = new SimpleDateFormat(DATE_PARTEN); public static Date cachedParseDate(String str) { try { return format.parse(str); } catch (ParseException e) { e.printStackTrace(); } return null; } public static String cachedFormatDate(Date date) { return format.format(date); } public static Date parseDate(String str) { SimpleDateFormat tempFormat = new SimpleDateFormat(DATE_PARTEN); try { return tempFormat.parse(str); } catch (ParseException e) { e.printStackTrace(); } return null; } public static String formatDate(Date date) { SimpleDateFormat tempFormat = new SimpleDateFormat(DATE_PARTEN); return tempFormat.format(date); } }
在本机上测试, 10W次 字符串->Date与 10W次 Date> 字符串:
package com.haitao.test; import java.util.Date; import com.haitao.utils.SimpleDateFormatUtils; public class SimpleDateFormatTest { private static int COUNT = 0; /** * 生成日期字符串数据 */ public static String[] genrateDateStr(int count) { String[] array = new String[count]; for(int i = 0; i < count; i++) { array[i] = SimpleDateFormatUtils.cachedFormatDate(new Date()); } return array; } /** * 生成日期数据 */ public static Date[] genrateDate(int count) { String[] strArray = genrateDateStr(count); Date[] dateArray = new Date[count]; for(int i = 0; i < count; i++) { dateArray[i] = SimpleDateFormatUtils.cachedParseDate(strArray[i]); } return dateArray; } /** * 缓存SimpleDateFormat对象, 转换String->Date */ public void cachedParseDateTest(String dateStr) { long start = System.currentTimeMillis(); for(int i = 0; i < COUNT; i++) { SimpleDateFormatUtils.cachedParseDate(dateStr); } long end = System.currentTimeMillis(); log("cachedParseDate cost:" + (end - start) + "ms."); } /** * 缓存SimpleDateFormat对象, 转换Date->String */ public void cachedFormatDateTest(Date date) { long start = System.currentTimeMillis(); for(int i = 0; i < COUNT; i++) { SimpleDateFormatUtils.cachedFormatDate(date); } long end = System.currentTimeMillis(); log("cachedFormatDate cost:" + (end - start) + "ms."); } /** * 不缓存转换String->Date */ public void parseDateTest(String dateStr) { long start = System.currentTimeMillis(); for(int i = 0; i < COUNT; i++) { SimpleDateFormatUtils.parseDate(dateStr); } long end = System.currentTimeMillis(); log("ParseDate cost:" + (end - start) + "ms."); } /** * 不缓存转换Date->String */ public void formatDateTest(Date date) { long start = System.currentTimeMillis(); for(int i = 0; i < COUNT; i++) { SimpleDateFormatUtils.formatDate(date); } long end = System.currentTimeMillis(); log("formatDate cost:" + (end - start) + "ms."); } public void log(String message) { System.out.println(message); } public static void main(String[] args) { SimpleDateFormatTest sdf = new SimpleDateFormatTest(); SimpleDateFormatTest.COUNT = 100000; String dateStr = "2010-11-20 00:50:42.703"; sdf.cachedParseDateTest(dateStr); sdf.parseDateTest(dateStr); sdf.cachedFormatDateTest(new Date()); sdf.formatDateTest(new Date()); } }
得到如下测试结果:
cachedParseDate cost: 593ms.
ParseDate cost: 1485ms.
cachedFormatDate cost: 328ms.
formatDate cost: 1187ms.
很明显的可以看出通过静态化SimpleDateFormat对象,Date->String 与 String->Date 速度提高了3倍以上.
但是如果在多线程环境下,会造成格式化日期错误, 因此需要借助于ThreadLocal来完成安全的日期格式化:
package com.haitao.utils; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public final class SimpleDateFormatUtils { public static final String DATE_PARTEN = "yyyy-MM-dd HH:mm:ss.SSS"; /** * 线程安全转换 String -> Date */ public static Date safeParseDate(String dateStr) { try { return getFormat().parse(dateStr); } catch (ParseException e) { e.printStackTrace(); } return null; } /** * 线程安全格式化 Date -> String */ public static String safeFormatDate(Date date) { return getFormat().format(date); } /** * 借助ThreadLocal完成对每个线程第一次调用时初始化SimpleDateFormat对象 */ private static ThreadLocal<SimpleDateFormat> threadLocal = new ThreadLocal<SimpleDateFormat>(){ protected synchronized SimpleDateFormat initialValue() { return new SimpleDateFormat(DATE_PARTEN); } }; /** * 获取当前线程中的安全SimpleDateFormat对象 */ private static DateFormat getFormat(){ return (DateFormat)threadLocal.get(); } }
测试方法,同样使用10W次 字符串->Date与 10W次 Date> 字符串:
package com.haitao.test; import java.util.Date; import com.haitao.concurrency.FormatDateConcurrencyTask; import com.haitao.concurrency.ParseDateConcurrencyTask; public class SimpleDateFormatMutiThreadTest { private static final int N = 100000; public static void main(String[] args) throws Exception { Date[] dateArray = SimpleDateFormatTest.genrateDate(N); String[] stringArray = SimpleDateFormatTest.genrateDateStr(N); // 并发任务, stringArray任务数据, 10000传入每个线程处理任务数据个数 // 这里会生成10个线程的线程池来处理 ParseDateConcurrencyTask pdct = new ParseDateConcurrencyTask(stringArray, 10000); pdct.run(); // 并发任务, dataArray任务数据, 10000传入每个线程处理任务数据个数 // 这里会生成10个线程的线程池来处理 FormatDateConcurrencyTask fdct = new FormatDateConcurrencyTask(dateArray, 10000); fdct.run(); } }
并发的代码就不贴了,这个我自己写了一个单机的mapReduce并发任务框架,太乱,还没来得及整理,有时间给大家分享一下.
测试结果如下:
safeParseDate cost:359ms.
safeFormatDate cost:297ms.
可以看到测试结果比单线程cached模型都效率高,当然这里是由于多线程处理,在所有线程执行完毕进行最后统计,所以速度会这么快,在单线程效果下会比cached模型略微低一点,大概50ms左右的样子.
优化完毕,结论是通过在当前线程内缓存SimpleDateFormat既可以达到线程安全,又可以提升3倍以上的执行效率:)
发表评论
-
import static简化代码
2011-11-03 00:10 1705喜欢定义常量的哥们你伤不起啊,好处当然是大大滴,但是定义的名字 ... -
Java永远的伤-中国1927年12月31日午夜
2011-08-15 20:44 3903话说在中国1927年12月31日午 ... -
高性能的SimpleDateFormat
2011-07-18 23:35 3874以前写过一篇 , 《SimpleDateFormat性能调优》 ... -
xss漏洞之进制转换
2011-07-18 01:17 11289SQL注入的事件已经是上个世纪最令人头疼的攻击方法,21世纪又 ... -
tomcat关不掉的原因
2011-07-12 23:51 43574tomcat/bin 目录下的catalina.sh是比较常用 ... -
接口调用频率限制代码
2011-06-28 20:49 10621有很多时候我们写的代码不是你想跑多快就能跑多快的, 因为一些陈 ... -
java调用linux命令传递参数问题
2011-05-18 02:04 10745简单的不带通配符linux命令调用非常简单,使用Runtime ... -
Java位运算的优势
2011-04-09 01:58 2298在Java中对数据的运算,有很好的规范支持,尤其是针对二进制的 ... -
Facebook BigPipe技术
2011-01-04 00:37 2703关于web应用,从html的产生,到客户端浏览器的渲染, ... -
JMX学习笔记(三)-MXBean
2010-11-10 11:25 5007在MBean中有只要遵循以下两个规则,我们就可以在jc ... -
JMX学习笔记(二)-Notification
2010-11-07 15:25 9040Notification 通知,也可理解为消息,有通知,必 ... -
JMX学习笔记(一)-MBean
2010-10-16 16:27 13661JMX 即 Java Management Ex ... -
cookie安全
2010-07-06 01:09 4157cookie的domian,path,expires, ... -
native2ascii转换后仍然乱码
2010-04-18 17:47 1823native2ascii转换的时候如果不带-encoding ... -
JPA换进下慎用entity
2010-01-26 11:36 2640今天跟一个同事调试代码,突然发现,诸如findUser ... -
http session原理
2009-12-02 00:41 2871大家都知道session是web中在服务器端保存用户状 ... -
java中获得当前目录的各种方法
2009-09-04 11:21 14397Java本来就是跨平台的编程工具,所以当然要做跨平台的 ... -
String、StringBuffer与StringBuilder
2009-04-26 22:04 1940先不废话了,来段程序: package com.tuz; ...
相关推荐
在处理复杂格式时,可能会有性能上的考虑,因为正则表达式在处理大量数据时可能会变得效率低下。此外,为了兼容性,这个实现可能还需要处理不同的区域设置和语言环境。 在实际项目中,除了自定义实现外,还可以考虑...
SimpleDateFormat类的线程安全问题是因为它使用了缓存机制来提高解析和格式化的性能。缓存机制使用了一个缓存数组来存储解析和格式化的结果,但是这个缓存数组是共享的,这意味着在多线程环境中,多个线程可能会同时...
SimpleDateFormat 详解 SimpleDateFormat 是 Java 语言中的一种日期和时间格式化类,用于将日期和时间格式...通过合理地使用 SimpleDateFormat,我们可以实现日期和时间的高效格式化和解析,提高程序的性能和可读性。
2. **缓存问题**:`SimpleDateFormat`在内部使用了缓存来提高性能,但这个缓存也是线程不安全的。在并发情况下,两个线程同时尝试修改或获取缓存的值,可能导致数据混乱。 3. **解析和格式化操作**:这两个操作不是...
SimpleDateFormat 使用详解 SimpleDateFormat 是 Java 中的一个日期和时间格式化类,它继承自 DateFormat 类。SimpleDateFormat 允许用户以各种方式格式化日期和时间,例如以年、月、日、时、分、秒等不同的格式来...
### SimpleDateFormat的常用方法说明 #### 一、简介 `SimpleDateFormat`是Java中用于格式化日期和时间的一个类。它允许我们自定义日期/时间的显示格式,这在实际开发中非常有用,尤其是在处理不同地区或语言环境下...
在Java编程语言中,`SimpleDateFormat`和`Calendar`是两个重要的日期和时间处理类,它们在处理日期格式化、解析以及日期计算方面扮演着重要角色。本文将深入探讨这两个类的功能、用法以及它们之间的关系。 `...
"深入理解Java:SimpleDateFormat安全的时间格式化" 在Java中,SimpleDateFormat是一个非常常用的类,用来对日期字符串进行解析和格式化输出。但是,如果使用不小心会导致非常微妙和难以调试的问题,因为DateFormat...
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); date.setTime(time); System.out.println(sdf.format(date)); 发现时间于想要的时间不符,请运行Time.reg文件
在Java编程语言中,`SimpleDateFormat` 是一个非常重要的日期和时间格式化工具类,它允许程序员以特定的模式来解析和格式化日期。当我们需要从系统获取当前时间并按照自定义格式显示时,`SimpleDateFormat` 就派上了...
日期操作。。。基础的SimpleDateFormat格式化日期!!操作!》初级学习代码
目录SimpleDateFormat诡异bug复现SimpleDateFormat诡异bug字符串日期转Date日期(parse)Date日期转String类型(format)SimpleDateFormat出现bug的原因如何解决SimpleDateFormat多线程安全问题局部变量使用...
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("mm:ss"); // 创建时间对象 Date date = new Date(finalI * 1000); // 执行时间格式化并打印结果 System.out.println(simpleDateFormat.format(date...
1.创建SimpleDateFormat对象,确定日期被格式化的格式 2.使用循环,在循环中调用Thread的sleep方法,让线程休眠1s后打印当前时间的字符串
这种方法虽然能够解决线程安全问题,但是会降低程序的并发性能。 2. **使用ThreadLocal**:对于每个线程创建独立的`SimpleDateFormat`实例,可以通过`ThreadLocal`实现。这样,每个线程都有自己的`SimpleDateFormat...
Java 8引入了`java.time`包,其中的`DateTimeFormatter`类提供了更现代且性能更好的日期时间格式化功能。它是线程安全的,并且提供了更多的日期时间格式选项。 在学习过程中,你可以通过提供的源代码实例深入理解...
"Java多线程环境下SimpleDateFormat类安全转换" 在Java多线程环境下,SimpleDateFormat类的使用可能会出现线程安全问题。本文主要介绍了Java多线程环境下SimpleDateFormat类的安全转换,通过示例代码详细介绍了如何...
NULL 博文链接:https://chaoyi.iteye.com/blog/2082317
在性能要求较高的场景下,可以考虑使用`java.time`包中的`DateTimeFormatter`类,它是Java 8及更高版本引入的,提供了更高效且更易用的日期时间格式化功能。 总结来说,`SimpleDateFormat`是Java中处理日期和时间...