今天偶然想起翻翻tomcat源码,果然每次翻源码都有不小的收获。
下面我带领大家看下tomcat8中的ConcurrentDateFormat源码和实现。
源码如下:
/**
* {@link SimpleDateFormat}的线程安全包装器。
* 不使用ThreadLocal,创建足够的SimpleDateFormat对象来满足并发性要求。
*/
public class ConcurrentDateFormat {
private final String format;
private final Locale locale;
private final TimeZone timezone;
private final Queue<SimpleDateFormat> queue = new ConcurrentLinkedQueue<>();
public static final String RFC1123_DATE = "EEE, dd MMM yyyy HH:mm:ss zzz";
public static final TimeZone GMT = TimeZone.getTimeZone("GMT");
private static final ConcurrentDateFormat FORMAT_RFC1123;
static {
FORMAT_RFC1123 = new ConcurrentDateFormat(RFC1123_DATE, Locale.US, GMT);
}
public static String formatRfc1123(Date date) {
return FORMAT_RFC1123.format(date);
}
public ConcurrentDateFormat(String format, Locale locale,
TimeZone timezone) {
this.format = format;
this.locale = locale;
this.timezone = timezone;
SimpleDateFormat initial = createInstance();
queue.add(initial);
}
public String format(Date date) {
SimpleDateFormat sdf = queue.poll();
if (sdf == null) {
sdf = createInstance();
}
String result = sdf.format(date);
queue.add(sdf);
return result;
}
private SimpleDateFormat createInstance() {
SimpleDateFormat sdf = new SimpleDateFormat(format, locale);
sdf.setTimeZone(timezone);
return sdf;
}
}
tomcat8中并没有采用ThreadLocal的实现方式,而是用了一个并发队列。
format
时先从队列中弹出一个SimpleDateFormat,为null时则创建并添加进队列。
这样随着线程数的增长,队列中的SimpleDateFormat对象将会趋于饱和,减少高并发下对象的创建,提高性能。