2016-02-10 5 views
0

Если я объявляю ConcurrentHashMap<Person, Interests> - Если я отменяют Person.hashCode() привести в то же хэш-значение [плохой дизайн ты!], Так что все элементы расположены в том же ведре - Как по умолчанию concurrencyLevel [16] поможет одновременно пишет?Как установить параметр concurrencyLevel в ConcurrentHashMap, если мой hashCode() слаб?

Я понимаю, что в приведенном выше случае записи в карте не распространяются. Следовательно, при изменении конкретного <K,V>, замок устанавливается на один и только один существующий hashBucket поэтому никакой другой поток не может модифицировать другие <K1,V1> и выгоду от параллельных модификаций

+1

Мне кажется, что ваше центральное допущение неверно. Javadoc явно заявляет, что '' concurrencyLevel' влияет на внутренний размер. – EJP

+0

Как это влияет на внутренний размер? Скажем, у меня есть 100 элементов на моей карте, и все они входят в тот же Bucket. Поскольку все элементы попадают под один и тот же сегмент, только один поток может изменять карту, а остальные блокируются. – nsk

ответ

1

В ConcurrentHashMap операций записи может блокировать друг друга только тогда, когда они пишут в том же сегменте. Тем не менее, когда ваши объекты Person имеют одинаковый результат hashCode(), все они будут размещены в одном сегменте HashMap.

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

+0

Могу ли я знать, как корреляция сегментации и внутренней калибровки. Если есть 100 элементов - равномерно распределенных [размер 1-го ведра], как мой concurrencyLevel [16] разделится на сегменты - это 100/16, что составляет примерно 16 элементов на сегмент? Или это сегментирование на ведро? – nsk

+0

Параметр concurrencyLevel фактически определяет, сколько потоков может получить доступ к вашей коллекции в данный момент времени. Если ваш уровень параллелизма равен 16, и у вас есть 50 потоков, пытающихся записать 50 ведер, то только 16 потоков в большинстве случаев смогут сделать это параллельно. Остальные будут ждать «слота». Однако, если все 50 потоков попытаются получить доступ к одному ведру, только один из них будет успешным, а остальные будут ждать. Параметр ConcurrencyLevel должен быть установлен на основе количества потоков, которые вы ожидаете получить доступ к своей коллекции. Если вы ожидаете 50 потоков, установите для параметра ConcurrencyLevel значение 50. –