Сегодня я задал вопрос в своем интервью. Вопрос в том, что Collections.synchronizedMap() - это , используемый для синхронизации карты, которые по умолчанию не являются потокобезопасными, как hashmap. Его вопрос в том, что мы можем передать любую карту внутри этого метода. Итак, каков эффект, когда мы передаем хэш-таблицу внутри этого метода, потому что хэш-таблица по умолчанию синхронизирована.Что происходит, когда мы передаем хеш-таблицу внутри Collections.synchronizedMap()
ответ
Если вы видите код в SynchronizedCollection
.Методы делегируют вызов к основной коллекции, но при добавлении синхронизируются блок сверху вызова что-то вроде этого
public int size() {
synchronized (mutex) {return c.size();}
}
Реализации размера выглядит в HashTable
классе
public synchronized int size() {
return count;
}
Таким образом, если вы переходите в HashTable
в SynchronizedCollection
, поток, обращающийся к SynchronizedCollection
, должен будет занять блокировки на 2 уровнях один раз для синхронизированного блока, а другой для синхронизированного метода. Если есть другие потоки, напрямую связанные с объектом HashTable, они могут блокировать потоки, используя SynchronizedCollection
, даже когда поток получил блокировку на SynchronizedCollection
.
Это будет получить завернутые в SynchronizedMap
из java.util.Collections
:
public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {
return new SynchronizedMap<>(m);
}
synchronizedMap()
метод не делает различия между типами Map
с перешедших в него.
Вы бы два уровня синхронизации: один на уровне самой синхронизированной карты, реализуемый объектом мьютекса, и один на уровне обернутых например:
public boolean isEmpty() {
// first level synchronization
synchronized(mutex) {
// second level synchronization if c is a Hashtable
return c.isEmpty();
}
}
Дополнительная синхронизация не требуется и может привести к снижению производительности.
Еще один эффект заключается в том, что вы не сможете использовать API от Hashtable
, как Hashtable#elements
, так как обернутая коллекция теперь строго представляет собой экземпляр Map
.
Поведение карты будет одинаковым, но на производительность будет влиять, поскольку каждый метод будет приобретать две блокировки синхронизации вместо одной.
Например, рассмотрим вызов метода size()
на полученной карте. Реализация в Collections.SynchronizedMap
класса выглядит следующим образом:
public int size() {
synchronized(mutex) {return m.size();} // first lock
}
... где m.size()
называет реализацию в Hashtable
:
public synchronized int size() { // second lock
return count;
}
первый объект замок является mutex
поле в SynchronizedMap
. Вторая блокировка неявная - сам экземпляр Hashtable
.
«Его вопрос только в том, что мы можем передать любую карту внутри этого метода».
Ответ да, потому что конструктор SynchronizedMap
принимает каждое Map
в его подписи.
«Так что эффект, когда мы передаем хэш-таблицу внутри этого метода, поскольку Хеш по умолчанию синхронизирована»
Ответ: Мы показываем невежество в ConcurrentHashMap
, который, скорее всего, инструмент будет использоваться вместо реализации блокировки.
- 1. Что происходит внутри, когда мы делаем downcasting?
- 2. Что именно происходит, когда мы пишем window.open()?
- 3. , что происходит, когда мы передаем строку как из параметров в C#
- 4. Что происходит, когда мы называем IUknown :: Release
- 5. Что именно происходит, когда мы используем ajax
- 6. Что происходит, когда мы обновляем веб-страницу?
- 7. Что происходит, когда мы используем updatepanel?
- 8. Что происходит, когда мы переписываем существующий файл?
- 9. Что происходит, когда мы вызываем ServiceWorkerRegistration.pushManager.subscribe()?
- 10. Что происходит, когда мы перезаряжаем модули Elixir?
- 11. Что происходит, когда мы вызываем requestLocationUpdates()?
- 12. Что происходит, когда мы создаем объект интерфейса?
- 13. Что происходит, когда мы произвольно используем ==?
- 14. Что происходит, когда мы вызываем $ (document) .ready()
- 15. Что происходит, когда мы разыскиваем указатель FILE?
- 16. Что происходит, когда мы делаем networkstream.write()?
- 17. Что происходит под капотом, когда мы представляемViewController?
- 18. Что происходит, когда мы вызываем метод ArrayList.add()?
- 19. Что происходит, когда мы запускаем класс PHP?
- 20. Что происходит, когда мы перезаписываем cv :: Mat.data
- 21. Collections.synchronizedMap
- 22. Что происходит внутри, когда внешний поток закрыт?
- 23. Почему мы передаем UIViewController классу UINavigationController?
- 24. Что происходит с exe, когда мы подписываем его?
- 25. Что происходит, когда мы пытаемся получить доступ к элементам массива?
- 26. Как получить между записями от поиска, когда мы передаем диапазон:
- 27. Что происходит, когда происходит тайм-аут WebClientProtocol
- 28. Что происходит, когда мы не указываем тип данных аргументов в функции и передаем ему параметры при вызове?
- 29. Что происходит внутри $ .each()?
- 30. Что такое беззнаковый тип, который мы передаем параметру?
Копия ответа Natix? – user219882
Я написал ответ параллельно с ним, я думаю, я не уверен, почему он приведен ниже, плюс я дал одну причину, почему бы не сделать это. –