Caching wrapper for digest computation
Volatile won't do anything here, as this basically only affects the reference to the map, not the contents of the map.

As for ConcurrentHashMap (as opposed to explicit synchronizing I suppose): this depends. If you want to make absolutely sure that no digest is ever computed twice, stick to your approach. If you just want general concurrency, but can accept that eventually in race-conditions, digest is called twice for the same input (sidenote: I suppose digest is deterministic, so that two calls with the same input yield the same result), you may simply repace the map with a ConcurrentHashMap and the whole method with:

return cache.computeIfAbsent(input, this::doDigest);