Это потокобезопасно? - PullRequest
       8

Это потокобезопасно?

2 голосов
/ 07 февраля 2011

Я хочу сделать свой класс потокобезопасным без больших накладных расходов. Экземпляры будут редко использоваться одновременно, но это может произойти. Большая часть класса является неизменяемой, в качестве кэша используется только один изменяемый член:

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);

После назначения карта никогда не изменяется.

Это не проблема, когда два потока вычисляют кэш параллельно, так как значение будет одинаковым. Дополнительные накладные расходы на слово, введенное дважды, являются приемлемыми.

Когда поток не увидит значение, вычисленное другим протектором, он вычислит его без необходимости, и это приемлемо. Это не произойдет из-за изменчивости. Когда поток видит значение, вычисленное другим протектором, это нормально.

Единственная возможная проблема - поток, видящий несогласованное состояние (например, частично заполненную карту). Может ли это случиться?

Примечания:

  1. Я действительно хочу, чтобы на всю карту мягко ссылались, здесь нет смысла использовать карту с использованием программных клавиш или значений.

  2. Я знаю о ConcurrentHashMap и, возможно, буду его использовать в любом случае, но мне любопытно, работает ли volatile только.

Ответы [ 2 ]

4 голосов
/ 07 февраля 2011

Единственной возможной проблемой будет противоречивое состояние потока (например, частично заполненная карта). Может ли это случиться?

Нет. Действия, выполняемые в потоке, должны выполняться так, как если бы они были выполнены по порядку. Запись изменчивой переменной происходит до любого чтения этого значения. Следовательно, инициализация карты происходит до того, как какой-либо поток прочитает ссылку на карту из поля.

1 голос
/ 07 февраля 2011

Проблема с использованием мягкой ссылки заключается в том, что вы можете потерять всю карту / кеш после GC. Это означает, что производительность вашего приложения может сильно пострадать. Вам лучше использовать кеш с политикой выселения, чтобы у вас никогда не возникало этой проблемы.

Летучие вещества здесь не делают безопасными операции.

Вы не показали весь свой код, возможно, мы могли бы предложить несколько советов о том, как вы могли бы улучшить свой код, например. ваш пример кода должен скомпилироваться;)

...