2017-02-21 32 views
0

現在、ConcurrentHashMapを使用しています。これは、org.apache.commons.lang.RandomStringUtils#randomAlphanumericを使用して生成する一意のIDに基づいていくつかのファイルを保存しています。一意のIDを正しく生成して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)が偽と私は別のスレッドが来て、同じキーを追加マップに追加する前に、私は1 Cu​​stomFileを持つことになりますが地図の代わりに2つ。私はチャンスが非常に小さいことを知っているが、私はこれを考慮に入れたい。

この状況ではどのような方法が最適ですか、各ファイルに一意のIDがあることを確認するにはどうすればよいですか。

+0

本当に別の操作としてIDを生成する必要がありますか? –

答えて

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でこのメソッドの実装は、同意の問題を回避するために、正しく​​です。

0

#putIfAbsent()を使用すると、マップにアイテムをアトミックに配置するか、そうでない場合はnullを返すので、nullではなくwhileループに入れることができます。
CustomFileインスタンスがまだないため、コードを少しリファクタリングする必要があります。
ダミーアイテムを最初に配置してから実際のオブジェクトに置き換えることができますが、他のスレッドがその時間内にそのオブジェクトを読み取ると、別の同期の問題が発生する可能性があります。

関連する問題