Project: Tomcat
Bug 48170 Unnecessary synchronization by JspFactory.getDefaultFactory contributes to stability problems
Reported: 2009-11-10 18:04:01 | Status: resolved fixed

I have a soak test at constant load that is initially stable. Within the hour, an ever increasing number of blocked threads develops. The vast majority of threads are in JSP rendering, blocked on JspFactory.getDefaultFactory(). The server eventually crashes. We are running Java 6. Upon code inspection, there appears to be no real reason for synchronizing the getDefaultFactory() and setDefaultFactory() as the setter is called only once upon startup when the sub-class loads. Patching the jar, I tried three other experiments: 1) Removing the synchronized keyword entirely. 2) Locking on an inner static class instead of the JspFactory.class. 3) Using volatile for the static member variable. Both experiments #1 and #3 showed vastly better stability. I was able to double the throughput of the server without seeing increasing number of blocked threads. Experiment #2 yielded the same behavior as the original code. Thus, no other code is synchronizing on JspFactory.class. Rather, there seem to be some sort of contention in the java.lang.Class monitor. Using volatile would preserve the multi-threading semantics while avoiding contributing to the instability issue.

Files changed in fix:
java/javax/servlet/jsp/JspFactory.java