转载请注明出处: https://blog.csdn.net/jevonsCSDN/article/details/83092795 【Jevons’Blog】
SimpleDateFormat是一个非线程安全类,当高并发时,若共用一个format对象,则会出现线程安全问题,比如前一个format结果会被后一个format结果顶掉,这不符合我们的预期;而如果每用一次就new一次,当使用频率高时却又会造成非常大的开销,这种结果更不理想。网上大部分采用ThreadLocal来实现,虽然解决了线程安全问题,但并不能解决开销问题,同时若出现线程假死等长期占用资源的现象还会存在内存泄漏的隐患,所以 我就写了个线程安全的类池,用本人的老爷机实测10万并发耗时6秒左右,格式池设置最大值为50,每种格式类型的SimpleDateFormatSub对象数量在使用的时候都维持在30-60之间,基本满足要求。
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.Vector;
/**
* 日期格式化类池(线程安全)
* @author Zhang Haowen
* @date 2018年10月12日
*/
public class SimpleDateFormatPoolKit {
//格式器类池
private static final Map<PatternType, Vector<SimpleDateFormatSub>> TYPE_MAP = new HashMap<PatternType, Vector<SimpleDateFormatSub>>();
private SimpleDateFormatPoolKit(){};
private static final int maxSize = 0x32;//格式池最大值:50
static {
//初始化格式器类池
for(PatternType patternType: PatternType.values()){
TYPE_MAP.put(patternType, new Vector<SimpleDateFormatSub>());
}
}
/**
* 获取格式器
* @param patternType 格式类型
* @return
*/
public static synchronized SimpleDateFormatSub getFormator(PatternType patternType){
if(TYPE_MAP.get(patternType).size()==0){
return new SimpleDateFormatSub(patternType);//如果类池为空,新建格式器
}else{
return TYPE_MAP.get(patternType).remove(0);//从类池中取出格式器
}
}
/**
* 获取格式器
* @return
*/
public static synchronized SimpleDateFormatSub getFormator(){
return getFormator(PatternType.values()[0]);//default
}
/**
* 释放资源,将格式器放回相应的类池
* @param sdf
*/
public static synchronized void free(SimpleDateFormatSub sdf){
if(TYPE_MAP.get(sdf.getPatternType()).size()<maxSize){
TYPE_MAP.get(sdf.getPatternType()).add(sdf);
}
}
/**
* 静态内部类
* @author Zhang Haowen
* @date 2018年10月12日
*/
public static class SimpleDateFormatSub extends SimpleDateFormat{
private static final long serialVersionUID = 1L;
private PatternType patternType;
public SimpleDateFormatSub(PatternType patternType) {
super.applyPattern(patternType.toString());;
this.setPatternType(patternType);
}
public PatternType getPatternType() {
return patternType;
}
public void setPatternType(PatternType patternType) {
this.patternType = patternType;
}
}
/**
* 格式类型
* @author Zhang Haowen
* @date 2018年10月12日
*/
public enum PatternType{
YEAR_TO_DAY ("yyyy-MM-dd"),
YEAR_TO_SECOND ("yyyy-MM-dd HH:mm:ss");
private String patternValue;
private PatternType(String patternValue) {
this.patternValue=patternValue;
}
@Override
public String toString() {
return this.patternValue;
}
}
}
/**
* 使用样例
* @param args
*/
public static void main(String[] args) {
SimpleDateFormatSub formator = SimpleDateFormatPoolKit.getFormator(PatternType.YEAR_TO_SECOND);
try {
System.out.println(formator.format(new Date()));
System.out.println(formator.parse("2018-08-08 12:11:55"));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
SimpleDateFormatPoolKit.free(formator);//释放资源
}
}