потокобезопасность карты при использовании UUID в качестве ключа
Потоковая безопасность карт на самом деле не имеет никакого отношения к рассматриваемому ключевому объекту. То, что UUID.randomUUID()
возвращает уникальный UUID, не гарантирует безопасность потока. Проблема заключается в синхронизации памяти и том, как потоки будут видеть и публиковать изменения на картах и координировать множественные операции с картами.
Вопрос в том, имеет ли updateContent()
состояние гонки?
Да, это так. Прежде всего, вы не можете обновить Map
, используя несколько потоков, без использования синхронизированной или одновременной реализации Map
. ConcurrentHashMap
позаботится об изменениях карт и публикации памяти между потоками, чтобы синхронизировать их. Но поскольку вы выполняете несколько операций с картами, которые должны быть скоординированы, вам необходимо добавить дополнительную синхронизацию.
Если это так, то необходимо синхронизировать весь метод updateContent()
илиДостаточно ли просто использовать ConcurrentHashMap?
Поскольку вы вносите несколько изменений в 2 карты, вам нужно будет использовать synchronized
или иным образом заблокировать несколько операций. Как только вы это сделаете, вам не нужно будет использовать ConcurrentHashMap
. Вы можете либо сделать метод synchronized
, заблокировать одну из карт, либо сделать конкретный final Object lockObject = new Object()
, чтобы использовать его для блокировки операций.
Например, без блокировки нет ничего, что защищаетThread1, чтобы увидеть, что content1
не содержит идентификатор XXX, а затем перейдите к проверке content2
прямо перед тем, как thread2 добавит его к content1
. Так что thread1 перезапишет data
в thread2, а это не то, что вы хотели бы предположить.