Синхронизирует ли получение синхронизированной коллекции из класса коллекций класс? - PullRequest
3 голосов
/ 28 мая 2019

Я пытаюсь понять, что делают synchronizedCollection, synchronizedList, synchronizedMap, synchronizedSet и другие подобные методы. Из того, что я понимаю, синхронизация может быть сделана на блоках и методах, а не на классах, так скажем, если у меня есть hashmap.

HashMap<Integer,String> hashMap = new HashMap<Integer,String>();
HashMap<Integer,String> syncHashMap = Collections.synchronizedMap(hashMap);

Вопросы

  1. Так же, как приведенный выше код просто синхронизировал весь syncHashMap класс или каждый метод внутри него?

  2. Если мы можем просто использовать потокобезопасную коллекцию, такую ​​как ConcurrentHashMap или SynchronizedMap в сценарии с многопоточностью, тогда зачем Collections.synchronizedMap(hashMap) и другие подобные методы в Коллекции класс

Буду глубоко признателен за некоторые направления в этом, заранее спасибо.

Ответы [ 4 ]

1 голос
/ 28 мая 2019
  1. Итак, приведенный выше код просто синхронизировал весь класс syncHashMap или все методы внутри него?

Не уверен, что вы подразумеваете под синхронизированным целым классом syncHashMap и каждый метод внутри него .

Если вы посмотрите на исходный код метода Collections.synchronizedMap(hashMap), вы обнаружите, что оно использует ключевое слово synchronized для украшения каждого метода исходной карты.Что означает для оформленного объекта карты, вы можете вызвать только один из его методов за один раз.Но на разные карты их можно вызывать одновременно.

Вы можете найти использование их здесь. ConcurrentHashMap против синхронизированной HashMap
0 голосов
/ 28 мая 2019

Прежде чем ответить на ваш вопрос, давайте повторим некоторые основы синхронизации

  • Синхронизация всегда выполняется для объекта / экземпляра. Каждый синхронизированный экземпляр защищен блокировкой (называемой мьютексом).
  • Любой поток, вызывающий синхронизированный метод объекта, должен сначала получить эту блокировку, а затем вызвать этот метод.
  • Это получение блокировки не требуется, если вызывается несинхронизированный метод.

Чтобы ответить на ваши вопросы:

  1. Так что приведенный выше код просто синхронизировал весь класс syncHashMap или каждый метод внутри него ?

Да, это так. Просто посмотрите на исходный код Collections.SynchronizedMap здесь . Обратите внимание, что почти у каждого метода есть блок synchronized (mutex) .

  1. Если мы можем просто использовать потокобезопасную коллекцию, такую ​​как ConcurrentHashMap или SynchronizedMap, в сценарии многопоточности, тогда зачем нужен Collections.synchronizedMap (hashMap) и другие подобные методы в классе Collections?

Ну, есть недостатки при синхронизации каждого метода (включая методы только для чтения). Это замедляет операцию чтения без необходимости, и, следовательно, ваше наблюдение правильно, т. Е. Использовать реализации, такие как ConcurrentHashMap, которые блокируют только метод, который модифицирует коллекцию. Методы только для чтения не синхронизируются и, следовательно, работают быстрее в многопоточном сценарии с одновременными операциями чтения / записи.

Единственное преимущество, которое предлагает Collections.synchronizedMap, - это сохранение порядка введенных ключей. Поэтому, когда вам это нужно, вы используете Collections.synchronizedMap.

0 голосов
/ 28 мая 2019

Есть несколько терминов, касающихся темы, о которой вы спрашиваете.

Синхронизация

Существует ряд интерфейсов и классов, которые помогают синхронизировать ваш код между потоками.A Семафор , CyclicBarrier или синхронные коллекции, такие как BlockingQueue .Список этих классов см. В пакете java.util.concurrent .

Блок synchronized также является способом синхронизации, хотя для правильного использования требуется большеопыт работы.

Mutex

Различные языки (и библиотеки) по-разному реализуют стандартный мьютекс.Идея остается прежней - чтобы приступить к выполнению определенного кода, токена MUTually EXclusive, необходимо получить мьютекс.В Java это приобретение происходит перед входом в блок synchronized.

Потоковая безопасность

Проще говоря, класс является поточно-ориентированным, когда все его методы могут быть доступны в любом порядке из любого числа потоков одновременно.Существует несколько способов обеспечения безопасности потоков.Например, строки являются потокобезопасными.Они не синхронизированы, но они неизменны, что также обеспечивает безопасность потоков.Все Collections.synchronized*() методы возвращают потокобезопасные оболочки для коллекций, за исключением того, что весь будущий * (* см. случай-до ) доступ к ним выполняется через эти оболочки (поэтому для новичков это хорошее правило вызыватьCollections.synchronized*() на new объекты только.

Ответ

Имея знания из предыдущих абзацев, чтобы ответить на ваш вопрос: нет, он не синхронизирует класс. Он не изменяетсявообще оригинальная реализация Collection. Тем не менее она создает потокобезопасный синхронизированный изменяемый вид прокси для чтения и записи для этого класса.

0 голосов
/ 28 мая 2019

Насколько я понимаю, Collections.synchronizedMap не гарантирует, что значения полей внутри хранимых объектов будут синхронизированы, но каждая запись внутри карты будет синхронизироваться при изменении в методе synchronized.Это не гарантирует ничего другого.Всякий раз, когда синхронизированная карта изменяется в другом потоке, другие ссылки на ту же карту в других потоках синхронизируются.

Это мое поверхностное понимание этого в соответствии с этим источником , а также Javaдокументация.

...