1

Наше многопоточное многопользовательское приложение имеет много возможностей использования Hashtable. Безопасно ли заменять экземпляры Hashtable экземплярами ConcurrentHashmap для повышения производительности? Будет ли побочный эффект?Безопасно ли заменить все вхождения Hashtable на ConcurrentHashmap?

+1

Некоторые тонкие отличия: http://stackoverflow.com/questions/12646404/concurrenthashmap-and-hashtable-in-java – christopher

+0

Это сравнение производительности HashMap и ConcurrentHashMap может быть полезно http://stackoverflow.com/questions/1378310/performance-concurrenthashmap-vs-hashmap – GuiSim

+0

Есть ли аналогичное сравнение производительности Hashtable и ConcurrentHashmap? – dpkp

ответ

2

Безопасно ли заменять экземпляры Hashtable экземплярами ConcurrentHashmap для повышения производительности?

В большинстве случаев он должен быть безопасным и обеспечивать лучшую производительность. Усилия по изменению зависят от того, используете ли вы интерфейс Map или Hashtable.

Будет ли побочный эффект?

Возможны побочные эффекты, если ваше приложение сразу же сможет получить доступ к элементам, которые были помещены в карту другим потоком.

С JavaDoc на ConcurrentHashMap:

Retrieval operations (including get) generally do not block, so may overlap 
with update operations (including put and remove). Retrievals reflect the 
results of the most recently completed update operations holding upon their onset. 

Редактировать: уточнить на «немедленно» рассмотреть нить 1 добавляет элемент А к карте и в то время как запись выполняется поток 2 пытается, существует ли в карта. С Hashtable поток 2 будет заблокирован до записи, поэтому проверка вернет true, но при использовании ConcurrentHashMap он вернет false, так как поток 2 не будет заблокирован и операция записи еще не завершена (таким образом, поток 2 увидит устаревшую версию ведро).

+1

«... если ваш приложение ожидает немедленного доступа к элементам, которые были помещены в карту другим потоком ». Это предполагает некоторое общее понимание для * немедленно *, которое является нечетким термином в мире параллелизма. Также кажется, что «ConcurrentHashMap» не предлагает некоторую своевременную гарантию, предлагаемую «Hashtable», но это не так. –

+0

@ DimitarDimitrov Вот почему я сказал, что _might_ будет побочным эффектом. Я имею в виду, что если один поток помещает что-то в карту, а другой поток читает его почти в тот же момент (операция записи не заканчивается при запуске операции чтения), вы не можете ожидать получить новое значение в результатах операции чтения, когда используя ConcurrentHashMap, но из-за синхронизации в Hashtable вы гарантированно получите его.В конце концов, это может быть не актуально, но это возможный побочный эффект. – Thomas

+0

Это интуитивный ответ, но я бы назвал его неправильным, так как он внушает неверное представление о гарантиях. Вы не можете положиться на вероятность того, что поток 'get()' будет припаркован, а через некоторое время он увидит последний «put», с которым он синхронизирован. Вы должны иметь возможность обрабатывать случай, когда ваш 'get()' получил блокировку до того же 'put()', и если вы уже это сделали, вам будет лучше с 'ConcurrentHashMap', потому что вы получаете все тот же но с почти всегда более высокой производительностью в качестве дополнения. –

2

В зависимости от размера ваших объектов Hashtable вы можете получить некоторую прибыль от прироста, переключившись на ConcurrentHashmap.

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

Таблицы сами по себе являются потокобезопасными и оба реализуют интерфейс карты, поэтому замена должна быть относительно простой.