java - Why is TimeZone.getTimeZone(id) synchronized, and why this isn't documented? - Stack Overflow

有JavaEE系统一个服务器实例耗尽32核CPU,看到有大量如下线程堆栈信息:

"[ACTIVE] ExecuteThread: '255' for queue: 'weblogic.kernel.Default (self-tuning)'" daemon prio=10 tid=0x00002aaad2ba8000 nid=0x247f waiting for monitor entry [0x00002aaaefa37000]

   java.lang.Thread.State: BLOCKED (on object monitor)

         at java.util.TimeZone.getDefaultInAppContext(TimeZone.java:627)

         - locked <0x00000006e05a43e8> (a java.lang.Class for java.util.TimeZone)

         at java.util.TimeZone.getDefaultRef(TimeZone.java:523)

         at java.util.GregorianCalendar.<init>(GregorianCalendar.java:541)

         at com.aspire.mo.framework.util.DateUtil.getCacheDate(DateUtil.java:292)

         at com.itindex.mo.framework.base.QueryTemplate$2.query(QueryTemplate.java:279)

 

上面这个锁导致了50多个线程被阻塞。

 

分析:在使用大量内存的大型多线程环境中,TimeZone是一个瓶颈,它使用了一个 synchronized HashMap

 

建议:使用Joda-Time时间类来代替Calendar类消除这个瓶颈。

 

参见下列Java 日期类性能测试:

 

// date-short:
    new Date();
//date-long: 
    new Date(year, month, date, hrs, min, sec);
// calendar:
    Calendar cal = Calendar.getInstance(TimeZone);
    cal.set(year, month, date, hourOfDay, minute, second)
    cal.getTime();
// cached-cleared-calendar:
//    Same as calendar, but with Calendar.getInstance() outside of the loop, 
//    and a cal.clear() call in the loop.

I tested single threaded performance, where 1M Dates were created using each method in a single thread. Then multi-threaded with 4 threads, each thread creating 250k Dates. In other words: both methods ended up creating the same number of Dates.

 
 

看到Calendar日期类性能最差。

 

参考:

http://blog.lick-me.org/2013/08/java-date-performance-subtleties/

http://stackoverflow.com/questions/5682236/why-is-timezone-gettimezoneid-synchronized-and-why-this-isnt-documented

 

你可能感兴趣的:(java)