2017-02-21 16 views
0

В настоящее время я использую ConcurrentHashMap, в котором храню некоторые файлы на основе уникального идентификатора, который я генерирую, используя org.apache.commons.lang.RandomStringUtils#randomAlphanumeric.Как правильно сгенерировать уникальный идентификатор и сохранить его в ConcurrentHashMap

Мой текущий подход заключается в следующем:

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) возвращает ложное и, прежде чем я добавить его к карте другой поток приходит и добавляет тот же ключ, у меня будет один CustomFile в вместо двух. Я знаю, что шансы очень малы, но я хочу принять это во внимание.

Итак, каков наилучший подход в этой ситуации и как я могу гарантировать, что у меня также есть уникальный идентификатор для каждого файла?

+0

Вам действительно нужно сгенерировать идентификатор как отдельную операцию? –

ответ

2

Вы можете использовать putIfAbsent(K key, V value):

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, чтобы избежать проблем согласования.

0

Вы можете использовать #putIfAbsent(), который будет атомарно размещать элемент на карте или возвращать значение null в противном случае, чтобы вы могли вставлять свой цикл while, а не null.
Вам нужно будет немного обработать ваш код, так как у вас еще нет экземпляра CustomFile.
Одна вещь, которую вы можете сделать, это сначала поместить фиктивный элемент, а затем заменить его на ваш реальный объект после его создания, но это может вызвать другие проблемы синхронизации, если другие потоки будут читать этот объект за время.

 Смежные вопросы

  • Нет связанных вопросов^_^