"DateFormat 不是同步的。建议为每个线程创建独立的格式实例。如果多个线程同时访问一个格式,则它必须保持外部同步。"----摘自JDK文档中文版
首先让我们看看一个简单的方法
public static Date toDate(String dateStr) {
SimpleDateFormat p= new SimpleDateFormat("yyyyMMdd");
try{
return p.parse(dateStr);
}catch (ParseException e) {
}
return null;
}
这个方法是把形如"20110101"这样的字符串转换成Date类型;同时方法是支持多线程并发访问的,但是这个是有代价的,因为每次方法调用都要创建一个SimpleDateFormat 对象。
很自然的我们就想到以下的改进,将SimpleDateFormat声明为静态全局变量
private static final SimpleDateFormat PATTERN = new SimpleDateFormat("yyyyMMdd");
同时为了保证多线程同步访问,方法需要加锁
public synchronied static Date toDate(String dateStr) {
try{
return PATTERN.parse(dateStr);
}catch (ParseException e) {
}
return null;
}
这样的优化还是不够的,因为在多线程争用的情况下,性能不佳。最好是每个线程都有自己的DateFormat,这样既不会发生争用,而且对于每个线程都只创建一个DateFormat对象。
ThreadLocal正好可以满足这种需求。这里不多做解释了,我们一步到位:
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
public class DateFormatFactory {
private static final Map<String, ThreadLocal<SimpleDateFormat>> pool = new HashMap<String, ThreadLocal<SimpleDateFormat>>();
private static final Object lock = new Object();
public static SimpleDateFormat getDateFormat(String pattern) {
ThreadLocal<SimpleDateFormat> tl = pool.get(pattern);
if (tl == null) {
synchronized (lock) {
tl = pool.get(pattern);
if (tl == null) {
final String p = pattern;
tl = new ThreadLocal<SimpleDateFormat>() {
protected synchronized SimpleDateFormat initialValue() {
return new SimpleDateFormat(p);
}
};
pool.put(p, tl);
}
}
}
return tl.get();
}
}
public static Date toDate(String dateStr,String pattern) {
try{
return getDateFormat(pattern).parse(dateStr);
}catch (ParseException e) {
}
return null;
}
上面还增加了对不同Pattern的ThreadLocal的缓存,这样对于每一个线程每一种pattern都只要创建一个SimpleDateFormat对象,多线程访问无需争用。
代码还要很多待改进的地方,如对于非法的pattern不要缓存,是否存在更快、更节约内存的方法。。。。。。
匆匆忙忙,如有错误的地方望不吝赐教!
分享到:
相关推荐
NULL 博文链接:https://zhaoshunxin.iteye.com/blog/1291905
调用该类中的方法,实现字符串于日期类型之间的转换,以及包括数据库中的日期类型,避免了代码的重复.
主要介绍了Java多线程编程中使用DateFormat类,文中介绍了三种相关的并发使用方法,需要的朋友可以参考下
SimpleDateFormat类不是线程安全的,这意味着在多线程环境下,如果多个线程同时访问同一个SimpleDateFormat实例,可能会导致各种问题,例如转化的时间不正确、报错、线程被挂死等等。 知识点2: 创建...
java 使用DateFormat类获取系统的当前时间 java 使用DateFormat类获取系统的当前时间
DateFormatManager dateformat = new DateFormatManager( new char[] { DateString.CENTURY, DateString.MONTH, DateString.DAY, DateString.YEAR, DateString.WEEK, DateString.HOUR_OF_DAY, DateString.MINUTE,...
Date Format with "-"
NULL 博文链接:https://bert82503.iteye.com/blog/2106022
dateformat - 一个优秀的node.js日期格化包
前端项目-jquery-dateFormat,它是一个jquery插件,用于使用javascript格式化日期输出。
jquery-dateFormat, 使用JavaScript格式化日期输出的jQuery插件 使用JavaScript格式输出日期输出的jQuery dateformat插件- 拥有的,jQuery是最小的日期格式库。 ! 安装下载最新的jquery.dateFormat.js 或者 jquery....
sql取日期格式中的年月天时分秒 sql取日期格式中的年月天时分秒
日期格式 Steven Levithan出色的函数的node.... var dateFormat = require ( "dateformat" ) ; var now = new Date ( ) ; // Basic usage dateFormat ( now , "dddd, mmmm dS, yyyy, h:MM:ss TT" ) ; // Saturday, June
yyyy-MM-dd形式 js timeformat dateformat
Java中DateFormat类.pdf 学习资料 复习资料 教学资源
用于转换时间格式, ... DateFormat dateFormat = new DateFormat(); 二. String timeString=dateFormat.DateFormat("yyyy-MM-dd HH:m:s",time); 参数1:填写需要的格式 参数2:填写需要改变的时间
EXTJS_DATEFORMAT 日期格式对应,网上找到的,挺好用的
dateFormat日期格式化。
个人资源
16_常用API_第2天(正则表达式、Date、DateFormat、Calendar)_讲义