Ok. Just out of curiosity, I will do one change that will reduce scope for lock time, and possibly reduce impact: this by moving actual construction out of sync section. I wish I could easily test if it has any measurable effect; but at least there should not be much downside.
On sharing: I am actually not as worried about memory usage, as that is mostly transient. Rather this is a performance optimization, as it avoids most String allocations and String.intern(), while still allowing String identity comparisons on keys; latter matters mostly with attribute names.
Regardless, I understand that with highest levels of concurrency different rules apply.
And I am actually excited to learn more, how to handle these cases, since they are bound to become more common. Also, this same problem with apply to Jackson JSON processor (another OSS project I authored).
I'll have to see what's the best way to avoid sync'ing altogether; and add a new configuration property as well.
Thank you for your help here!