This is the invalidation thread involved in the deadlock:
And this is the other:
In thread '49', the session has been invalidated and the SessionDispatcher is attempting to shut down the Monitor for that session. In the process of doing that it grabs the lock on the contexts instance (a synchronized Set):
...
private Set contexts = Collections.synchronizedSet(new HashSet());
...
public void shutdown() {
synchronized (contexts){
Iterator i = contexts.iterator();
while (i.hasNext()) {
ServletContext context = (ServletContext) i.next();
notifySessionShutdown(session, context);
...
As part of notifySessionShutdown(), it wants to grab the lock for the SessionMonitors (a plain HashMap):
...
private static void notifySessionShutdown(final HttpSession session, final ServletContext context) {
SessionDispatcher sessionDispatcher = lookupSessionDispatcher(context);
if (sessionDispatcher != null) {
sessionDispatcher.notifySessionShutdown(session);
synchronized (SessionMonitors) {
...
In thread '35', we see that it grabbed the lock for the SessionMonitors:
protected void checkSession(HttpSession session) throws SessionExpiredException {
try {
final String id = getId(session);
final Monitor monitor;
synchronized (SessionMonitors) {
if (!SessionMonitors.containsKey(id)) {
monitor = new Monitor(id, session);
SessionMonitors.put(id, monitor);
} else {
monitor = (Monitor) SessionMonitors.get(id);
}
monitor.addInSessionContext(context);
But as part of calling addInSessionContext(), it needs the lock on the contexts (a synchronized Set) instance being held by thread '49':
public void addInSessionContext(ServletContext context) {
contexts.add(context);
}
Subsequent request threads just start piling up waiting on the lock for the SessionMonitors:
This is the invalidation thread involved in the deadlock:
And this is the other:
In thread '49', the session has been invalidated and the SessionDispatcher is attempting to shut down the Monitor for that session. In the process of doing that it grabs the lock on the contexts instance (a synchronized Set):
As part of notifySessionShutdown(), it wants to grab the lock for the SessionMonitors (a plain HashMap):
In thread '35', we see that it grabbed the lock for the SessionMonitors:
But as part of calling addInSessionContext(), it needs the lock on the contexts (a synchronized Set) instance being held by thread '49':
public void addInSessionContext(ServletContext context) { contexts.add(context); }
Subsequent request threads just start piling up waiting on the lock for the SessionMonitors: