Как рекомендует z5h, вам нужно защитить свое состояние (fileLastUpdate> mapsLastUpdate) той же блокировкой, которая используется для сохранения атомарной перезагрузки файла.
Я думаю об этом так: посмотреть на все переменные-члены в классе и выяснить, какие гарантии безопасности потоков им нужны. В вашем случае, ни один из членов (File, long, HashMap - хорошо, я предполагаю, что HashMap) не является потокобезопасным, и, следовательно, все они должны быть защищены блокировкой. Они также все участвуют в инварианте (все они изменяются вместе) вместе, поэтому они должны быть защищены той же блокировкой.
Ваш код, обновленный и использующий аннотации (это просто информация, они ничего не приводят в исполнение!), Предложенный Java Concurrency In Practice (отличная книга для всех Java разработчики должны читать:))
/**
* Lookup table that automatically reloads itself from a file
* when the filechanges.
*/
@ThreadSafe
public class LookupTable
{
@GuardedBy("this")
private long mapLastUpdate;
@GuardedBy("this")
private final File file;
@GuardedBy("this")
private Map<String, String> map;
public LookupTable(File file)
{
this.file = file;
this.map = loadMap()
}
public synchronized String getValue(String key)
{
long fileLastUpdate = file.lastModified();
if (fileLastUpdate > this.mapLastUpdate)
{
// Only the first thread should run the code in the synchronized block.
// The other threads will wait until it is finished. Then skip it.
Map newMap = loadMap();
this.map = newMap;
this.mapLastUpdate = fileLastUpdate;
}
return map.get(key);
}
private synchronized Map<String, String> loadMap()
{
// Load map from file.
return null;
}
}
Это будет безопасно, но оно полностью синхронизировано: только один поток выполняет поиск на карте одновременно. Если вам нужен параллелизм при поиске, вам понадобится более сложная схема. Реализация будет зависеть, среди прочего, от того, позволят ли потоки видеть старую версию справочной таблицы во время загрузки новой.
Если вы сделали окончательный элемент карты и защитили его ReadWriteLock , вы можете получить некоторый удар. Трудно предсказать, сколько у вас может быть разногласий по этой блокировке, из ограниченной информации здесь.