繁体   English   中英

如何正确生成唯一的ID并将其存储在ConcurrentHashMap中

[英]How to properly generate a unique id and store it in a ConcurrentHashMap

我当前正在使用ConcurrentHashMap,其中基于我使用org.apache.commons.lang.RandomStringUtils#randomAlphanumeric生成的唯一ID存储一些文件。

我当前的方法是这样的:

private ConcurrentHashMap <String, CustomFile> fileIdMap = 
                     new ConcurrentHashMap <String, SwitchConfigurationFile>();

public void importFile () {       
    CustomFile file = new CustomFile (generateFileID(), param1, param2, param3, param4);
    fileIdMap.put (file.getID(), file);       
}

private String generateFileID () {
   String generatedValue = RandomStringUtils.randomAlphanumeric(5);
   while (fileIdMap.containsKey(generatedValue)) {
       generatedValue = RandomStringUtils.randomAlphanumeric(5);
   }
   //I was thinking here to put the generated value into the Map
   //but at this moment I don't have the CustomFile instance
   //and null values are not allowed
   //maybe:
   //fileIdMap.put (generatedValue, new CustomFile());
   return generatedValue;
}

我在想:如果fileIdMap.containsKey(generatedValue)返回false,并且在我将其添加到地图之前,另一个线程来添加相同的密钥,我将在地图中拥有一个CustomFile而不是两个。 我知道机会很小,但是我要考虑到这一点。

那么,在这种情况下最好的方法是什么,如何确保每个文件也具有唯一的ID?

您可以使用putIfAbsent(K键,V值)

private String generateFileID () {
   CustomFile file = new CustomFile();
   String generatedValue = RandomStringUtils.randomAlphanumeric(5);
   while (fileIdMap.putIfAbsent(generatedValue, file) != null) {
       generatedValue = RandomStringUtils.randomAlphanumeric(5);
   }
   return generatedValue;
}

ConcurrentHashMap中此方法的实现已正确synchronized以避免并发问题。

您可以使用#putIfAbsent() ,该方法会自动将该项放置在地图中,否则将返回null,因此您可以在不为null的情况下放入while循环。
由于您还没有CustomFile实例,因此需要重构代码。
您可以做的一件事是首先放置一个虚拟项目,然后在创建真实对象后将其替换,但是如果其他线程同时读取该对象,则这可能会引起另一个同步问题。

暂无
暂无

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

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