diff --git a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/FastDatePrinter.java b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/FastDatePrinter.java index 8468ff5bb..1eb1b4e80 100644 --- a/hutool-core/src/main/java/org/dromara/hutool/core/date/format/FastDatePrinter.java +++ b/hutool-core/src/main/java/org/dromara/hutool/core/date/format/FastDatePrinter.java @@ -17,11 +17,10 @@ package org.dromara.hutool.core.date.format; import org.dromara.hutool.core.date.format.parser.FastDateParser; +import org.dromara.hutool.core.text.StrUtil; -import java.util.Calendar; -import java.util.Date; -import java.util.Locale; -import java.util.TimeZone; +import java.util.*; +import java.util.concurrent.ConcurrentLinkedQueue; /** * {@link java.text.SimpleDateFormat} 的线程安全版本,用于将 {@link Date} 格式化输出
@@ -33,19 +32,25 @@ public class FastDatePrinter extends SimpleDateBasic implements DatePrinter { private static final long serialVersionUID = -6305750172255764887L; private final DatePattern datePattern; + /** + * 缓存的Calendar对象,用于减少对象创建。参考tomcat的ConcurrentDateFormat + */ + private final Queue queue; // Constructor // ----------------------------------------------------------------------- + /** * 构造,内部使用
* - * @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式 + * @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式 * @param timeZone 非空时区{@link TimeZone} - * @param locale 非空{@link Locale} 日期地理位置 + * @param locale 非空{@link Locale} 日期地理位置 */ public FastDatePrinter(final String pattern, final TimeZone timeZone, final Locale locale) { super(pattern, timeZone, locale); this.datePattern = new DatePattern(pattern, locale, timeZone); + this.queue = new ConcurrentLinkedQueue<>(); } // Format methods @@ -72,36 +77,28 @@ public class FastDatePrinter extends SimpleDateBasic implements DatePrinter { } @Override - public String format(final long millis) { - final Calendar c = Calendar.getInstance(timeZone, locale); - c.setTimeInMillis(millis); - return applyRulesToString(c); + public String format(final Date date) { + return format(date.getTime()); } @Override - public String format(final Date date) { - final Calendar c = Calendar.getInstance(timeZone, locale); - c.setTime(date); - return applyRulesToString(c); + public String format(final long millis) { + return format(millis, StrUtil.builder(datePattern.getEstimateLength())).toString(); } @Override public String format(final Calendar calendar) { - return format(calendar, new StringBuilder(datePattern.getEstimateLength())).toString(); + return format(calendar, StrUtil.builder(datePattern.getEstimateLength())).toString(); } @Override public B format(final Date date, final B buf) { - final Calendar c = Calendar.getInstance(timeZone, locale); - c.setTime(date); - return datePattern.applyRules(c, buf); + return format(date.getTime(), buf); } @Override public B format(final long millis, final B buf) { - final Calendar c = Calendar.getInstance(timeZone, locale); - c.setTimeInMillis(millis); - return datePattern.applyRules(c, buf); + return applyRules(millis, buf); } @Override @@ -115,17 +112,25 @@ 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. - * @return a String representation of the given Calendar. + * @param millis 时间戳 + * @param buf 待拼接的 Appendable + * @return buf 拼接后的Appendable */ - private String applyRulesToString(final Calendar c) { - return datePattern.applyRules(c, new StringBuilder(datePattern.getEstimateLength())).toString(); + private B applyRules(final long millis, final B buf) { + 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; } /** - *估算生成的日期字符串长度
+ * 估算生成的日期字符串长度
* 实际生成的字符串长度小于或等于此值 * * @return 日期字符串长度