这是一个设计问题,我试图找出哪个级别(应用程序,类,对象甚至更精细)我应该放置锁以确保原子性。
我有一个申请说Engine
,其中有一个class A
,其中一个方法包含一张地图。
class A{
public void methodA(){
Map<X,Y> testMap = Maps.newHashMap();
}
}
现在我有多个线程访问此地图。我想要确保的是此地图上的原子{读写}组合。我有的选择是
1.ConcurrentHashMap
2.Collections.synchronizedMap
3.static synchronizedMap outside the methodA
4.Application level locks using Redis or Memcache
我应该提到的是我正在考虑第4个选项,因为应用Engine
可能有多个实例。
现在,当多个线程尝试读取和写入地图时,我正面临竞争条件。
对于option1,我获得了桶级锁定,因为可以将不同的线程定向到Engine
app的不同实例
对于option2,我得到对象级锁定,它面临与1
相同的问题对于option3,我得到类级别锁定,它遭受多实例应用程序的相同缺陷
选项4似乎是最可行的选择。但是它会带来性能开销。因此,Java中有一些方法可以确保在类级别进行此锁定,而不允许线程修改应用程序的不同实例。
参考Chetan的评论,这个本地地图后来用于与数据库的dao交谈,该数据库是全局的,也就是遇到竞争条件的地方。
答案 0 :(得分:1)
的ConcurrentHashMap
即使所有操作在你“开始”时都是线程安全的,但它可能会或可能不会反映出'put'。
Collections.synchronizedMap
Collections.synchronizedMap(map)创建一个阻塞Map,这会降低性能,尽管确保一致性。仅当每个线程都需要具有地图的最新视图时才使用此选项
方法A之外的静态synchronizedMap
与3
使用Redis或Memcache进行应用程序级别锁定
根据我对你的问题的理解,只有这个选项才有意义。
这是我对你的要求的理解,如果我错了就纠正我,会相应地更新答案: - 你有'引擎'应用程序的多个实例(如多个JVM中的多个实例)。在将地图(每个实例都是本地的)保存到数据库中时,您必须避免竞争条件