Java 从ConcurrentHashMap中删除未使用的ReentrantLock

Java 从ConcurrentHashMap中删除未使用的ReentrantLock,java,concurrency,java.util.concurrent,concurrenthashmap,reentrantlock,Java,Concurrency,Java.util.concurrent,Concurrenthashmap,Reentrantlock,我在服务中有一个方法,它获取实体(如果存在的话),否则它会创建一个新的实体并返回(出于提问的目的,假设实体只是一个字符串) 方法由多个线程执行,因此如果其中两个线程将使用相同的值调用MethodgetOrCreateEntity,那么它们可以完成创建两个相同的对象,因此下一个getEntity调用将返回两个相同的对象,其中只允许一个对象 我试图通过将ConcurrentHashMap与ReentrantLock组合来锁定每个唯一的实体名称,一般来说,它工作得很好,当我试图用不再需要的锁删除映射条

我在服务中有一个方法,它获取实体(如果存在的话),否则它会创建一个新的实体并返回(出于提问的目的,假设实体只是一个字符串)

方法由多个线程执行,因此如果其中两个线程将使用相同的值调用Method
getOrCreateEntity
,那么它们可以完成创建两个相同的对象,因此下一个
getEntity
调用将返回两个相同的对象,其中只允许一个对象

我试图通过将
ConcurrentHashMap
ReentrantLock
组合来锁定每个唯一的实体名称,一般来说,它工作得很好,当我试图用不再需要的锁删除映射条目时会出现问题,然后在调用
unlock()时,我会得到
NullPointerException
方法

我希望对每个唯一值进行正确的同步

我的虚拟课堂用来测试工作概念

公共类实体服务{
私有静态最终ConcurrentHashMap lockMap=新ConcurrentHashMap();
私有静态最终列表entityList=new ArrayList();
公共字符串getOrCreateEntity(字符串entityName){
putIfAbsent(entityName,new ReentrantLock());
get(entityName.lock();
试一试{
返回getEntity(entityName).orelsGet(()->createEntity(entityName));
}最后{
lockMap.get(entityName.unlock();//tabName.equals(entityName))
.collect(Collectors.toList());
如果(result.size()>1){
抛出新的RuntimeException();
}else if(result.size()==1){
返回可选的.of(result.get(0));
}否则{
返回可选的.empty();
}
}
}
我的测试用例非常简单

class ReentrantLockServiceTest extends Specification {

    def service = new EntityService()

    def executor = Executors.newFixedThreadPool(200)

    def "test lock"(){
        expect:
        for (i in 0..20000) {
            executor.execute{ -> service.getOrCreateEntity(RandomUtils.nextInt(1,4) as String) }
        }
        Thread.sleep(5000)
    }

}
我缺少什么?也许有更好的并发类来执行我想要的行为