Java:请求的细粒度锁定?

Java:请求的细粒度锁定?,java,concurrency,locking,request-queueing,Java,Concurrency,Locking,Request Queueing,我正在尝试为以下场景创建细粒度锁定机制: 我有一个数据存储,里面有许多序列化的缓存对象。每个缓存都属于某个人、团体或公司,每个缓存可以通过以下四种方式之一进行修改:创建、删除、删除或插入。当一个缓存被修改时,我想阻止对它的访问。每个Cache都使用CacheLocation对象进行标识,该对象存储目录和文件名以及完整路径,以方便使用 目前,我在一个名为RequestQueue的类中使用数组列表,该类保存当前正在处理的CacheLocation对象。然后,当另一个线程进入时,它会检查队列,看看它请

我正在尝试为以下场景创建细粒度锁定机制:

我有一个数据存储,里面有许多序列化的
缓存
对象。每个
缓存
都属于某个人、团体或公司,每个
缓存
可以通过以下四种方式之一进行修改:创建、删除、删除或插入。当一个
缓存被修改时,我想阻止对它的访问。每个
Cache
都使用
CacheLocation
对象进行标识,该对象存储目录和文件名以及完整路径,以方便使用

目前,我在一个名为
RequestQueue
的类中使用数组列表,该类保存当前正在处理的
CacheLocation
对象。然后,当另一个线程进入时,它会检查队列,看看它请求的
CacheLocation
是否已经被使用。如果是这种情况,则使用while循环定期检查
CacheLocation
,直到将其放在那里的请求将其删除

我想这可能是一个想法,根据
BlockingQueue
值创建
CacheLocation
键的HashMap。这将导致大量的
BlockingQueue
对象,但我可以很好地管理队列


有没有更好的方法来实现这种细粒度锁定

如果我正确理解了您的描述,让您的设计保持相当简单的一种方法是:

  • 使用
    ConcurrentHashMap
    来存储缓存(我假设
    CacheLocation
    s是不可变的,或者至少从未突变过)
  • 确保通过锁定相关的
    CacheLocation
    对象来保护对缓存的所有访问

还有另一种非阻塞(但可能较慢)方法:

map.compute(someId, (key, value) -> {
  // atomic access to cache
  return null;
});

阅读我的相关问题和答案

不要使用while循环等待资源。两个或多个线程的条件可以同时为true并中断序列化访问。相反,使用syncronized或Lock我以前试过,但可能弄错了。我在RequestMap上调用get,查看requests CacheLocation是否在映射中(我想我需要使用ConcurrentHashMap),如果get返回了一个我正在同步的位置,并在对象上调用wait。我遇到的问题是,从另一个线程调用notify导致了一个非法MonitorStateException。不知道为什么,因为另一个线程应该已经创建了这个对象,但是它需要更多的研究:)是的,CacheLocation对象是不可变的。我目前使用ConcurrentHashMap将当前加载的缓存存储到内存中,而不是从光盘中读取它们,直到所有使用缓存的用户都发送了一个完成的请求。因此,我可以使用相同的技术来存储请求,我想:)我会尝试一下,让你知道我是如何得到请求的:)感谢大家的帮助,通过创建一个ConcurrentHashMap,以CacheLocation为键,以ReentrantLock为值,使它工作得很好。当一个变更请求进入时,它会检查映射,如果该缓存位置的条目不存在,它会创建一个新锁,通过调用Lock()获取它并将其添加到映射中。如果存在一个条目,它将获取锁并调用lock(),使线程等待。一旦拥有锁的线程释放它,下一个线程就会获得它,依此类推。这使我的设计美观整洁,希望很快=)再次感谢guys@AlexeiBlue这是一种方法——我更多地考虑使用
synchronized(cacheLocation)
块来保持简单。但效果是一样的。