TOMEE-4699 Fix ConcurrentModificationException in ThreadContext constructor - #2939
TOMEE-4699 Fix ConcurrentModificationException in ThreadContext constructor#2939JorrenH wants to merge 4 commits into
Conversation
To be precise, there are two mutexes involved: |
otbutz
left a comment
There was a problem hiding this comment.
I see no reason to copy the whole map?
Copying a ThreadContext iterates the source map. When the thread owning that context updates it at the same time the copy fails with a ConcurrentModificationException, which is what made tasks submitted to a managed executor disappear. The test copies a context on one thread while another updates it. It fails within a fraction of a second without the synchronized block in the copy constructor, and passes with it.
rzo1
left a comment
There was a problem hiding this comment.
LGTM, thanks for tracking this down.
I pushed a reproducer to the branch: ThreadContextCopyRaceTest copies a ThreadContext on one thread while another updates it. It fails within about half a second without the synchronized block and passes with it, so it should be a lot easier to work with than reproducing under load with a debugger attached. Feel free to change or drop it if you would rather keep the PR minimal.
I left one non-blocking note on the dataToString thread about toString() reading the size outside the lock.
|
@rzo1 Good to have a quick reproducer, thanks! I updated toString() such that the size is consistent with the entries since it's a quick win. Did pull the whole line into |
See Jira ticket for full context.
In summary:
.entrySet().iterator()internally, allowing it to cause aConcurrentModificationException.Note: ConcurrentHashMap does not work here because it does not allow
nullvalues.