upvote
Ironically to your point, I think adding a ConcurrentHashMap because it might be multithreaded eventually IS premature optimisation.

The work can be done in future to migrate to using ConcurrentHashMap when the feature to add multithreading support is added. There's no sense to add groundwork for unplanned, unimplemented features - that is premature optimisation in a nutshell.

reply
The point of the premature saying is to avoid additional effort in the name of unnecessary optimization, not to avoid optimization itself. Using a thing that's already right there because it might be better in some cases and is no more effort than the alternatives is not a problem.
reply
I can fully understand "bickering" about someone sprinkling their favourite data type over a codebase which consistently used a standard data type before. The argument that it might be multithreaded in the futurure does not hold if the rest of the code base clearly was not writen with that in mind. That could even be counter productive, should someone get the misguided idea that it was ready for it.

Make a (very) good argument, and suggest a realtistic path to change the whole codebase, but don't create inconsistency just because it is "better". It is not.

reply
I don’t expose it at the boundaries, just within functions. With everything outside of the function I take a Map interface in and/or return the Map out.

It makes no difference to the outside code.

reply
You are communicating with future readers of the code. The presence of ConcurrentHashMap will lead future engineers into believing the code is threadsafe. This isn't true, and believing it is dangerous.
reply
No, they'll believe that that specific map is thread safe.
reply
That's really not much better. No function is an island, as wise man almost once said.
reply
It’s actually a lot better. That’s literally the whole point of interfaces and polymorphism: to make it so the outside does not care about the implementation.
reply
I think you are in the wrong. But my reason is that when you support concurrency, every access and modification must be checked more carefully. By using a concurrent Map you are making me review the code as if it must support concurrency which is much harder. So I say don’t signal you want to support concurrency if you don’t need it.
reply
1) You don't need ConcurrentHashMap to make code thread-safe. That's the most extreme version that means that you need a thread-safe iterator too.

2) Locks are cheap

3) I seriously doubt that the difference between a Map and a ConcurrentHashMap is measurable in your app

Which means that both, the comments on your PRs are irrelevant and you are still going too far in your thread-safety. So you are both wrong.

What you are right about is to focus on network calls.

reply
Locks are cheap performance-wise (or at least they can be) but they’re easy to screw up and they can be difficult to performance test.

ConcurrentHashMap has the advantage of hiding the locking from me and more importantly has the advantage of being correct, and it can still use the same Map interface so if it’s eventually used downstream somewhere stuff like `compute` will work and it will be thread safe without and work with mutexes.

The argument I am making is that it is literally no extra work to use the ConcurrentHashMap, and in my benchmarks with JMH, it doesn’t perform significantly worse in a single-threaded context. It seems silly for anyone to try and save a nanosecond to use a regular HashMap in most cases.

reply
As soon as you have a couple of those ConcurrentHashMaps in scope with relationships between their elements, your concurrency story is screwed unless you've really thought everything out. I'd encourage using just plain HashMap to signal that there's no thread safety so you know to rethink everything if/when it comes up.
reply