2010-12-29 2 views
2

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

1. Текущее положение трейдера (общий целое, где «целое» является математический термин)

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

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

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

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

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

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

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

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

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

+1

Я бы посоветовал вам переформулировать свой вопрос. Это предполагает, что каждый прочитал книгу. Это ограничит количество полученных вами ответов. – Davidann

ответ

2

Таким образом, используя 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 замки, когда вы кладете все одновременный доступ объектов в данный момент должен обрабатывать свою собственную синхронизацию.

+0

Таким образом, проблема во втором примере заключается в том, что у Брокера есть блокировка, а затем на вызов трейдера, которому нужен замок на той же карте? – Pete

+0

Проблема в том, что карта является потокобезопасной, но любые изменяемые объекты на карте не являются потокобезопасными. –

+2

@Pete, как упомянул Питер Лоури - изменяемые объекты не являются потокобезопасными, если они сами не синхронизированы правильно. После ввода в CHM вы теряете любые новые точки синхронизации (захват блокировки). Все CHM получает (ну почти все) никогда не будет получать put-lock, поэтому, если поле объекта, на котором держится карта, изменилось, другие потоки могут не видеть этого изменения. –

3

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

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

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

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

+0

В этом случае отдельные отдельные сегменты сегментировали код логичным способом и упрощали его поддержку и разработку. Есть только немного общих, изменяемых данных, поэтому я думаю, что компромисс стоит того. Скорость не большая проблема, так как я не участвую в безумии, известной как «HFT». – Pete

+0

Если скорость не большая проблема, я бы использовал один замок на высоком уровне для коллекции и все в ней. (и убедитесь, что доступ как можно быстрее, нет вызовов IO и т. д.). Это самый простой вариант. –

+0

Правильно, стоимость контекстного переключателя потока значительна, поэтому вам нужно убедиться, что всякая работа будет достаточно дорогостоящей, чтобы ее стоило. Вот интересная ссылка, описывающая фактическую стоимость: http://blog.tsunanet.net/2010/11/how-long-does-it-take-to-make-context.html –

Смежные вопросы