快捷搜索:  汽车  科技

java时间格式化(线程安全的时间格式化FastDateFormat)

java时间格式化(线程安全的时间格式化FastDateFormat)private static final FormatCache<FastDateFormat> cache= new FormatCache<FastDateFormat>() { @Override protected FastDateFormat createInstance(final String pattern final TimeZone timeZone final Locale locale) { return new FastDateFormat(pattern timeZone locale); } }; public static FastDateFormat getInstance(final String pattern) { return

java时间格式化(线程安全的时间格式化FastDateFormat)(1)

FastDateFormat为什么线程安全SimpleDateFormat的线程不安全

大家都知道SimpleDateFormat是线程不安全的

protected Calendar calendar;

SimpleDateFormat中的calendar是成员变量,同实例多个线程下会共享该calendar对象

而在进行格式化的时候可能会由于第一个线程还没有格式化完成,而第二个线程已经将时间修改了的情况

private StringBuffer format(Date date StringBuffer toAppendTo FieldDelegate delegate) { // 如果第一个线程设置了时间之后还没有格式化为字符串,此时第二个线程将时间覆盖掉,就会出现线程安全问题 calendar.setTime(date); boolean useDateFormatSymbols = useDateFormatSymbols(); for (int i = 0; i < compiledpattern.length; ) { int tag = compiledPattern[i] >>> 8; int count = compiledPattern[i ] & 0xff; if (count == 255) { count = compiledPattern[i ] << 16; count |= compiledPattern[i ]; } switch (tag) { case TAG_QUOTE_ASCII_CHAR: toAppendTo.append((char)count); break; case TAG_QUOTE_CHARS: toAppendTo.append(compiledPattern i count); i = count; break; default: subFormat(tag count delegate toAppendTo useDateFormatSymbols); break; } } return toAppendTo; } FastDateFormat如何处理的呢

那么FastDateFormat为什么是线程安全的呢?首先FastDateFormat是有一个缓存的,在进行实例化的时候是通过cache缓存来获取实例的

private static final FormatCache<FastDateFormat> cache= new FormatCache<FastDateFormat>() { @Override protected FastDateFormat createInstance(final String pattern final TimeZone timeZone final Locale locale) { return new FastDateFormat(pattern timeZone locale); } }; public static FastDateFormat getInstance(final String pattern) { return cache.getInstance(pattern null null); }

将格式化格式、时区和国际化作为一个key存在了cInstanceCache中,cInstanceCache是一个ConcurrentHashMap,相当于相同的格式化格式、时区和国际化会使用同一个FastDateFormat实例

final MultipartKey key = new MultipartKey(pattern timeZone locale); F format = cInstanceCache.get(key); if (format == null) { format = createInstance(pattern timeZone locale); final F previousValue= cInstanceCache.putIfAbsent(key format); if (previousValue != null) { // another thread snuck in and did the same work // we should return the instance that is in ConcurrentMap format= previousValue; } }

而在进行格式化的时候Calendar使用的是方法内部的局部变量,是不会出现线程安全问题的

public String format(final Date date) { final Calendar c = newCalendar(); c.setTime(date); return applyRulesToString(c); }

猜您喜欢: