Использование ConcurrentHashMap устраняет проблемы с видимостью данных? - PullRequest
2 голосов
/ 29 декабря 2010

Я прочитал Java-параллелизм на практике и у меня остался вопрос: когда я использую ConcurrentHashMap, о каких проблемах параллелизма данных, обсуждаемых в первой части книги, мне все еще нужно беспокоиться?Вот пара примеров из одной из моих программ:

1.Текущая позиция трейдера (общее целое число, где 'integer' - математический термин)

Это число представляет то, чем в данный момент владеет объект trader, и определяет его состояние.Он должен прочитать свою позицию, чтобы знать, что делать (смотреть, чтобы начать новую позицию или управлять текущей).Методы Trader выполняются в своем собственном потоке.

Объект broker отвечает за установку позиции trader.Он будет устанавливать позицию каждый раз, когда исполняется один из ордеров трейдера.Broker методы выполняются в собственном потоке.

И trader, и broker находятся в одном пакете.Позиция реализована в виде пакета-приват static ConcurrentHashMap.Ключи являются идентификаторами объектов трейдера.Значения являются целочисленными.

Внешним по отношению к пакету является приложение.Он получает позиции трейдеров косвенно с публичным добытчиком.

Позиции будут меняться не чаще, чем раз в несколько минут, поэтому broker не будет часто касаться карты.Тем не менее, trader и приложение будут часто читать.Кроме того, у нас часто есть несколько трейдеров, читающих карту одновременно.

Итак, используя ConcurrentHashMap таким образом, мне не нужно работать над блокировкой и видимостью данных?ConcurrentHashMap позаботится обо всем?

2.Рынок (bid, ask, последние цены)

Примерно такая же ситуация, что и позиция, за исключением того, что broker будет очень часто обновлять цены (до 10 обновлений в секунду в часы занятости);обычно несколько раз в секунду).trader и приложение по-прежнему часто читают.Ключи карты теперь являются кодами, указывающими, какой запас или будущее, а значения являются объектами, которые содержат рыночные цены.

Кажется, все работает нормально, но после прочтения JCIP я понимаю, что программу все равно можно сломать, если что-то не реализовано правильно.В книге рассказывается о ConcurrentHashMap, но явно не говорится, какие проблемы из части I нам больше не нужно решать вручную. кажется , что мне не нужно synchronize ничего в этом случае.Это правильно?

Ответы [ 3 ]

3 голосов
/ 29 декабря 2010

Таким образом, используя ConcurrentHashMap таким образом, Мне не нужно работать с блокировкой и видимость данных? ConcurrentHashMap обо всем позаботится?

Это зависит от того, что на карте, если я правильно прочитал ваш пример, ситуация выглядит следующим образом

static final ConcurrentMap<Integer,Integer> map = ...

class Trader{

  public int doRead(){
      map.get(someId);
   }
}
class Broker{
   public void doWrite(){
      map.put(someId,someValue);
   }
}

Если это так, то да, обо всем параллельности позаботятся.

Однако, если карта выглядит как

static final ConcurrentMap<Integer,Trader> map = ..

    class Broker{
       public void doWrite(){
          map.get(someId).setPosition(somePosition);
       }
    }

Это НЕ ориентировано на многопотоковое исполнение, хотя ConcurrentHashMap блокируется при установке, все одновременные обращения к объектам в этой точке должны обрабатывать собственную синхронизацию.

3 голосов
/ 29 декабря 2010

Да, ConcurrentHashMap заботится о видимости и блокировке, пока:

  • значения, хранящиеся в карте, являются неизменными.Кажется верным в вашем описании, учитывая, что ваши объекты цен неизменны;
  • у вас нет операций на карте, которые должны быть атомарными и не могут быть выражены как отдельные вызовы API карты.Например, если вам нужна такая операция, как «считывание значения с карты, выполнение вычислений и возврат результата на карту», ​​чтобы она была атомарной, вам все равно нужно сохранять явную блокировку во время этой операции или, еще лучше, изменить приложение, чтобыиспользовать элементарные операции API карты, такие как get/put/putIfAbsent.
2 голосов
/ 30 декабря 2010

Если вы не говорите о более чем 100 000 обновлений / чтений в секунду, я бы не стал использовать несколько потоков. Причина в том, что потокобезопасные компоненты занимают много раз дольше, чем компоненты, которые не являются. Поэтому, если компоненту требуется 5-кратная дольше, чтобы обеспечить безопасность потоков, вам необходимо использовать более 5 потоков одновременно, чтобы обеспечить безубыточность, не говоря уже о том, чтобы идти быстрее.

Несколько потоков гораздо полезнее, когда вам приходится выполнять относительно дорогие операции. Обновление позиции или цены намного эффективнее, чем одна нить.

...