I don't mind being added at all!
In DefaultConverterManager.java:
I don't think there's a problem, assuming addConverterType, addConverter and setConverters are only called during servlet init. I tried to construct a pathological case where you get different states of the converters map depending on the order that getConverterAssignableFrom is called on various Class objects, but I couldn't do it. Even if one could construct such a monster, it'd be hard to argue that any of the possible states was actually wrong, and easy to argue that the creator of such a mess would deserve the resulting (very mild) nondeterminism. Am I missing something obvious?
So DefaultConverterManager looks OK to me. I was going to say that you need to restore the synchronized block in setConverters:
public void setConverters(Map<String, Converter> converters)
{
synchronized (this.converters)
{
this.converters.clear();
this.converters.putAll(converters);
}
}
to defend against concurrent calls to setConverters, but if there's a guarantee that it will be called at most once, during init, then you don't need the synchronized block. (If you have it, though, better to lock this.converters rather than this.)
You should take out the GuardedBy("this") comment for DefaultScriptSession.attributes. It's a final reference to a thread-safe object, so it doesn't need to be (and isn't) guarded.
In DefaultScriptSession.java:
I don't know how DefaultScriptSession.getAttributeNames is used, but if the returned iterator needs to be thread-safe or stable, I would copy the attributes key set and return an unmodifiable iterator over the results. If the result is used in a single thread and it's OK if changes occur during iteration (or if you know that they won't), then it's fine as is – ConcurrentHashMap iterators won't throw ConcurrentModificationException.
You must synchronize on conduits rather than this in addScript and countPersistentConnections and change the conduits field comment to GuardedBy("self").
Likewise you must synchronize on scripts rather than this in writeScripts and change the scripts field comment to GuardedBy("self"). Better yet, if scripts is mostly read/iterated and rarely modified, use CopyOnWriteArrayList and get rid of synchronization entirely for the scripts field.
I don't think you want the synchronized block in removeScriptConduit.
You aren't making essential use of AtomicLong or AtomicBoolean with lastAccessedTime and invalidated. They might as well be volatile. The only reason to use the Atomic flavors is if you need an atomic operation like compareAndSet.
Similarly, you don't need to declare attributes as a ConcurrentMap, since you aren't using any ConcurrentMap operations. It's fine as a Map. (Same goes for converters in DefaultConverterManager, btw.)
Mike have you been able to review the changes I made? Any time to push out a 2.06 in the coming weeks?