简体   繁体   English

在多线程环境中将HashSet用作非常简单的缓存是否安全?

[英]Is it safe to use HashSet as a very simple cache in a multi-threaded environment?

I realize there are similar questions/answers to this, but I can't seem to find exactly what I'm looking for. 我意识到也有类似的问题/答案,但是我似乎找不到确切的答案。

I'm looking to implement an in-memory cache that caches the result of a call to the DB, which is doing an existence check. 我正在寻求实现一个内存中的缓存,该缓存缓存对数据库的调用的结果,该数据库正在执行是否存在检查。 This existence check is quite expensive and once the object exists in the DB it will never be removed, so a very simple cache in-memory (in-process even) is all I need. 这种存在检查非常昂贵,并且一旦对象存在于数据库中就永远不会将其删除,因此我只需要一个非常简单的内存中缓存(甚至是进程内缓存)。 Once the DB call is made the process remembers the result of the existence check for that ID and shouldn't call the DB again. 进行数据库调用后,该过程将记住该ID的存在性检查结果,因此不应再次调用数据库。

(Maybe another thing to mention is if the object doesn't exist in the DB, it will be created). (也许要提到的另一件事是,如果数据库中不存在该对象,则将创建该对象)。

I'm using a HashSet (java) for this and just adding the ID to the set when the check/create is done, however this is a highly concurrent environment and I am unsure about the implications of HashSet's lack-of-threadsafeness. 我为此使用HashSet(java),并在完成检查/创建后仅将ID添加到集合中,但是,这是一个高度并发的环境,我不确定HashSet缺乏线程安全性的含义。

The code only ever uses the add() and contains() methods (no iteration). 该代码只使用过add()和contains()方法(没有迭代)。

I don't really care about a cache miss (and a resulting extra DB call) here and there, but what I'm wondering is if this pattern of add() and contains() being called on the set in concurrent threads could lead to more catastrophic errors. 我并不真的在乎缓存未命中(以及随之而来的额外的数据库调用),但是我想知道的是,在并发线程中调用set()和contains()的这种模式是否会导致更严重的错误。

You can use ConcurrentHashMap for multi threaded access and write operation. 您可以使用ConcurrentHashMap进行多线程访问和写入操作。 If you want only HashSet, you can ConcurrentHashSet derived from ConcurrentHashMap. 如果只需要HashSet,则可以从ConcurrentHashMap派生出ConcurrentHashSet。 You can use like this. 您可以这样使用。

Set<String> myConcurrentSet = ConcurrentHashMap.newKeySet();

No. If you want to use a Map in a multithreaded environment, use Collections.synchronizedMap(<map object>) or ConcurrentHashMap.newKeySet(); 否。如果要在多线程环境中使用Map ,请使用Collections.synchronizedMap(<map object>)ConcurrentHashMap.newKeySet(); :

Set<String> concurrentSet = Collections.synchronizedSet(new HashSet<>());

or... 要么...

Set<String> concurrentSet = ConcurrentHashMap.newKeySet();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM