On Sat, 3 Apr 2021 01:06:50 GMT, Florent Guillaume <github.com+592810+e...@openjdk.org> wrote:
>> Ok, thanks for pointing that out, I didn't realize that limitation. However >> using synchronizedMap is overkill as it locks every operation. As I read >> it, only structural changes like adding and removing keys from the map >> causes problems. Getting a value from the map does not. Therefore I would >> only need to synchronize the putIfAbsent() at 449, which is pretty minor. >> The expunging of the map is already synchronized in WeakHashMap. >> >> The original code was half the performance of this one. > > If you synchronize `putIfAbsent` but not `get` you'll still get the possible > infinite loop described in the SO post. Expunging entries is synchronized over an internal data structure, so if you synchronize puts only, nothing prevents expunge (called from get) from running in parallel with put. The original code performed big integer exponentiation inside a synchronized block, your code doesn't. I expect substantial performance gains even with synchronization around hash map access, this is why I asked about performance. ------------- PR: https://git.openjdk.java.net/jdk/pull/3296