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)
块来保持简单。但效果是一样的。