Операция поиска ConcurrentHashMap не блокируется?

согласно документам Java

Операции извлечения (включая получение) обычно не блокируются, поэтому могут пересекаться с операциями обновления (включая размещение и удаление). Извлечение отражает результаты самых последних завершенных операций обновления, удерживаемых при их начале. Для агрегатных операций, таких как putAll и clear, одновременные выборки могут отражать вставку или удаление только некоторых записей.

Вопрос: Предположим, что поток t1 обновляет пару ключ-значение (называемую x), а затем приходит другой поток t2 и хочет прочитать x, будет ли копия c1, созданная из x в начале t2, и t2 будет читать из этого скопировать c1


person Learner    schedule 12.05.2013    source источник


Ответы (2)


Извлечение отражает результаты самых последних завершенных операций обновления, удерживаемых на момент их начала.

завершенное слово здесь важно. Теперь ваш сценарий

 Suppose a thread t1 is updating a key-value pair(called x), and then other thread t2 comes and want to read x.

T2 прочитает значение, обновленное операцией, которая была завершена не в процессе. В вашем сценарии, если операция обновления потоком t1 не завершена, t2 не увидит обновленное значение. Копия не создается. Его простое время фундамента. Если к тому времени, когда поток t2 прочитает значение x и операция обновления t2 будет завершена, он увидит обновленное значение, иначе нет.

person M Sach    schedule 12.05.2013
comment
'иначе нет'. - откуда t2 увидит, так как старого значения больше не существует(оно находится в процессе обновления) когда t2 пришел читать - person Learner; 12.05.2013

Вопрос: Предположим, что поток t1 обновляет пару ключ-значение (называемую x), а затем приходит другой поток t2 и хочет прочитать x, будет ли копия c1, созданная из x в начале t2, и t2 будет читать из этого скопировать c1

По-разному. Если операция T1 завершена, T2 увидит это значение. В противном случае T2 увидит старое значение.

Из http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ConcurrentHashMap.html:

Извлечение отражает результаты самых последних завершенных операций обновления, удерживаемых при их начале. Для агрегатных операций, таких как putAll и clear, одновременные выборки могут отражать вставку или удаление только некоторых записей.

person goblinjuice    schedule 12.05.2013
comment
В противном случае T2 увидит старое значение. - а откуда увидит, так как старого значения уже нет(оно в процессе обновления) - person Learner; 12.05.2013
comment
@Naroji Старое значение будет существовать до тех пор, пока T1 не обновит его. Это то, что документация означает Complete. Надеюсь это поможет. - person goblinjuice; 12.05.2013
comment
спасибо за вклад. Если это так, то old_value, замененное на new_value, является атомарной операцией (CAS), верно? - person Learner; 12.05.2013
comment
@JavaGeek да, он должен быть атомарным и видимым для другого потока; иначе вся эта документация была бы бесполезна - person Eugene; 30.09.2018