2013-05-13 67 views
0

我试图创建以下情形细晶粒的锁定机制:Java:细粒度锁定请求?

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

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

我想这可能是一个想法,有一个HashMap的CacheLocation键与BlockingQueue值。这会产生大量的BlockingQueue对象,但我可以很好地管理队列。

有没有更好的方法来做这种细粒锁定?

+1

不要使用while循环等待资源。两个或多个线程可以同时具有该条件为真,并中断序列化访问。相反,使用syncronized或锁 – Evans 2013-05-13 11:45:03

+0

我以前试过,但可能错了。我正在调用getMap来查看请求CacheLocation是否在Map中(我想我需要使用ConcurrentHashMap),并且如果返回一个位置,我正在同步并调用对象的等待。我遇到的问题是被调用来从其他线程通知导致IllegalMonitorStateException。不知道为什么,因为另一个线程应该已经创建了对象,但它需要更多的研究:) – 2013-05-13 12:01:59

回答

1

如果我理解你的描述正确的,这将让你的设计相当简单的一个办法是:

  • 使用ConcurrentHashMap<CacheLocation, Cache>存储缓存(我假设CacheLocation s为不可变的,或者至少从来没有突变)
  • 确保您防护所有访问你的缓存与相关CacheLocation对象上的锁
+0

是的,CacheLocation对象是不可变的。我目前使用ConcurrentHashMap将当前加载的缓存存储到内存中,而不是从光盘读取它们,直到使用缓存的所有使用都发送完成的请求。所以我可以使用相同的技术来存储请求我猜:)我会试一试,让你知道我是如何得到一个:) – 2013-05-13 11:47:35

+0

感谢帮助球员,设法通过创建一个ConcurrentHashMap与CacheLocation很好地工作作为钥匙和ReentrantLock作为价值。当有更改请求进来时,它会检查地图,如果对于该CacheLocation不存在条目,它将创建一个新的Lock,通过调用lock()来获取它并将其添加到地图中。如果存在条目,则它抓住锁并调用lock(),导致线程等待。一旦拥有锁的线程释放它,下一个线程获取它,依此类推。这使我的设计保持良好和整洁,并希望快速=)再次感谢各位 – 2013-05-13 14:33:37

+0

@AlexeiBlue这是一种方法 - 我更多地考虑使用'synchronized(cacheLocation)'块来保持简单。但效果是一样的。 – assylias 2013-05-13 14:35:51

0

也有另一种无阻塞(但可能会更慢)的方法:

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

here我相关的问题和答案