concurrency bug: use ConcurrentHashMap for caching