JAVA 中的SimpleDateFormat 是非线程安全的 具体原因自己百度。
网上说用ThreadLocal 封装可以实现线程安全。
自己封装了下
private static final ThreadLocal<Map<String, DateFormat>>
messageFormat = new ThreadLocal<Map<String, DateFormat>>(){
public Map<String, DateFormat> initialValue(){
return new HashMap<String, DateFormat>();
}
};
/**
* 获取线程局部变量
* @param dateFormat
* @return
*/
private static DateFormat getDateFormat(String dateFormat) {
Map<String, DateFormat> formatters = messageFormat.get();
DateFormat formatter = formatters.get(dateFormat);
if (formatter == null)
{
formatter = new SimpleDateFormat(dateFormat);
formatters.put(dateFormat, formatter);
}
return formatter;
}
一个线程进行对字符串或者对日期进行格式化首先要获取SimpleDateFormat()对象。在这里就是调用getDateFormat() 方法获取传入 日期格式。 但是一个线程在一个请求当中可能多次获取不同的类型的日期,这个时候需要新建一个MAP 对象放入线程局部变量中。
如果是在tomcat 中使用请记得释放申请的线程变量。因为tomcat 是开启线程池来管理响应的线程。在tomcat源码中有说明,
平时的话如果在server.xml 里面配置
Connector port=”80” protocol=”HTTP/1.1” maxThreads=”600” minSpareThreads=”100” maxSpareThreads=”500” acceptCount=”700”
的话是明确指定线程池的配置。如果不指定。tomcat 启动的时候默认开启线程池。所以如果申请了很大的一块内存。会造成内存泄漏。**
如果想让垃圾收集器回收它,有两种方法
1:将该线程从tomcat线程池中去除,当一个线程被回收的时候何况它的成员变量呢,但是tomcat启动一般都会配置一个线程池进行优化,所有该方法不太现实。
2:调用 ThreadLocal 的 remove 方法 将对象从hread中的成员变量threadLocals 中删除掉。