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