This commit is contained in:
Looly 2024-10-10 17:39:51 +08:00
parent 4b5d556f32
commit 3e94c0a92d

View File

@ -17,11 +17,10 @@
package org.dromara.hutool.core.date.format; package org.dromara.hutool.core.date.format;
import org.dromara.hutool.core.date.format.parser.FastDateParser; import org.dromara.hutool.core.date.format.parser.FastDateParser;
import org.dromara.hutool.core.text.StrUtil;
import java.util.Calendar; import java.util.*;
import java.util.Date; import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.Locale;
import java.util.TimeZone;
/** /**
* {@link java.text.SimpleDateFormat} 的线程安全版本用于将 {@link Date} 格式化输出<br> * {@link java.text.SimpleDateFormat} 的线程安全版本用于将 {@link Date} 格式化输出<br>
@ -33,9 +32,14 @@ public class FastDatePrinter extends SimpleDateBasic implements DatePrinter {
private static final long serialVersionUID = -6305750172255764887L; private static final long serialVersionUID = -6305750172255764887L;
private final DatePattern datePattern; private final DatePattern datePattern;
/**
* 缓存的Calendar对象用于减少对象创建参考tomcat的ConcurrentDateFormat
*/
private final Queue<Calendar> queue;
// Constructor // Constructor
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
/** /**
* 构造内部使用<br> * 构造内部使用<br>
* *
@ -46,6 +50,7 @@ public class FastDatePrinter extends SimpleDateBasic implements DatePrinter {
public FastDatePrinter(final String pattern, final TimeZone timeZone, final Locale locale) { public FastDatePrinter(final String pattern, final TimeZone timeZone, final Locale locale) {
super(pattern, timeZone, locale); super(pattern, timeZone, locale);
this.datePattern = new DatePattern(pattern, locale, timeZone); this.datePattern = new DatePattern(pattern, locale, timeZone);
this.queue = new ConcurrentLinkedQueue<>();
} }
// Format methods // Format methods
@ -72,36 +77,28 @@ public class FastDatePrinter extends SimpleDateBasic implements DatePrinter {
} }
@Override @Override
public String format(final long millis) { public String format(final Date date) {
final Calendar c = Calendar.getInstance(timeZone, locale); return format(date.getTime());
c.setTimeInMillis(millis);
return applyRulesToString(c);
} }
@Override @Override
public String format(final Date date) { public String format(final long millis) {
final Calendar c = Calendar.getInstance(timeZone, locale); return format(millis, StrUtil.builder(datePattern.getEstimateLength())).toString();
c.setTime(date);
return applyRulesToString(c);
} }
@Override @Override
public String format(final Calendar calendar) { public String format(final Calendar calendar) {
return format(calendar, new StringBuilder(datePattern.getEstimateLength())).toString(); return format(calendar, StrUtil.builder(datePattern.getEstimateLength())).toString();
} }
@Override @Override
public <B extends Appendable> B format(final Date date, final B buf) { public <B extends Appendable> B format(final Date date, final B buf) {
final Calendar c = Calendar.getInstance(timeZone, locale); return format(date.getTime(), buf);
c.setTime(date);
return datePattern.applyRules(c, buf);
} }
@Override @Override
public <B extends Appendable> B format(final long millis, final B buf) { public <B extends Appendable> B format(final long millis, final B buf) {
final Calendar c = Calendar.getInstance(timeZone, locale); return applyRules(millis, buf);
c.setTimeInMillis(millis);
return datePattern.applyRules(c, buf);
} }
@Override @Override
@ -115,13 +112,21 @@ public class FastDatePrinter extends SimpleDateBasic implements DatePrinter {
} }
/** /**
* Creates a String representation of the given Calendar by applying the rules of this printer to it. * 根据规则将时间戳转换为Appendable复用Calendar对象避免创建新对象
* *
* @param c the Calender to apply the rules to. * @param millis 时间戳
* @return a String representation of the given Calendar. * @param buf 待拼接的 Appendable
* @return buf 拼接后的Appendable
*/ */
private String applyRulesToString(final Calendar c) { private <B extends Appendable> B applyRules(final long millis, final B buf) {
return datePattern.applyRules(c, new StringBuilder(datePattern.getEstimateLength())).toString(); Calendar calendar = queue.poll();
if (calendar == null) {
calendar = Calendar.getInstance(timeZone, locale);
}
calendar.setTimeInMillis(millis);
final B b = datePattern.applyRules(calendar, buf);
queue.offer(calendar);
return b;
} }
/** /**