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 日期类性能测试:
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/