Я хочу сделать свой класс потокобезопасным без больших накладных расходов.
Экземпляры будут редко использоваться одновременно, но это может произойти.
Большая часть класса является неизменяемой, в качестве кэша используется только один изменяемый член:
private volatile SoftReference<Map<String, Something>> cache
= new SoftReference(null);
, которому в конструкторе присваивается (не используется совместно) как
Map<String, Something> tmp = new HashMap<String, Something>();
tmp.put("a", new Something("a");
tmp.put("b", new Something("b");
cache = new SoftReference(tmp);
После назначения карта никогда не изменяется.
Это не проблема, когда два потока вычисляют кэш параллельно, так как значение будет одинаковым.
Дополнительные накладные расходы на слово, введенное дважды, являются приемлемыми.
Когда поток не увидит значение, вычисленное другим протектором, он вычислит его без необходимости, и это приемлемо.
Это не произойдет из-за изменчивости.
Когда поток видит значение, вычисленное другим протектором, это нормально.
Единственная возможная проблема - поток, видящий несогласованное состояние (например, частично заполненную карту).
Может ли это случиться?
Примечания:
Я действительно хочу, чтобы на всю карту мягко ссылались, здесь нет смысла использовать карту с использованием программных клавиш или значений.
Я знаю о ConcurrentHashMap и, возможно, буду его использовать в любом случае, но мне любопытно, работает ли volatile только.