У меня есть приложение, которое читает и записывает несколько файлов. Цель состоит в том, чтобы предотвратить чтение или запись определенного файла во время записи другим потоком. Я не хочу блокировать чтение и запись всех файлов во время записи одного файла, так как это вызывает ненужную блокировку.
Чтобы попытаться добиться этого, я использую concurrentHashMap вместе с синхронизированным блоком, но если есть лучшее решение, я открыт для него.
Вот примерный код.
private static final ConcurrentMap<String, String> lockMap = new ConcurrentHashMap();
private void createCache(String templatePath, String cachePath){
//get template
String temp = getTemplate(templatePath);
String myRand = randomString();
lockMap.put(cachePath,myRand);
// save cache file
try {
// ** is lockMap.get(cachePath) still threadsafe if another thread has changed the row's value?
synchronized ( lockMap.get(cachePath) ){
Files.write(Paths.get(cachePath),temp.getBytes(StandardCharsets.UTF_8));
}
} finally {
// remove lock if not locked by another thread in the meantime
lockMap.remove(cachePath, myRand);
}
}
private String getCache(String cachePath){
String output = null;
//only lock if this specific file is being written at the moment
if ( lockMap.contains(cachePath) ){
synchronized ( lockMap.get(cachePath) ){
output = getFile(cachePath);
}
} else {
output = getFile(cachePath);
}
return output;
}
// main event
private String cacheToString (String templatePath, String cachePath){
File cache = new File(cachePath);
if ( !cache.exists() ){
createCache(templatePath, cachePath)
}
return getCache(cachePath);
}
Проблема, с которой я столкнулся, заключается в том, что хотя поток снимет блокировку запрошенного файла только в том случае, если он не был изменен другим потоком, другой поток все же может обновить значение в lockMap для этой записи - если это произойдет, сбой синхронизации?