Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- >>710699
- synchronized (lock) {} работает так: он помечает, что участок кода, выполняющийся в фигурных скобках, может быть выполнен только если объект lock не залочен. Хоть и можно синхронизироваться относительно любого объекта, хорошей практикой считается использовать конструкцию final Object lock = new Object(), а не myMap, как ты предложил. myMap не катит потому, что в ходе работы программы может быть перезаписан, и если где-то выполняется synchronized(myMap)-лок, то другой synchronized(myMap)-лок теперь тоже может выполниться, ведь объекты лока-то разные.
- Самый простой способ сделать потокобезопасный HashMap - это синхронизировать все записи и чтения из него. У этого способа есть два ньюанса - 1. Это накладывает определенный оверхед на приложение, у тебя возможна ситуация, когда десять потоков ждут освобождения лока и тем самым ты никакого выигрыша от многопоточности не получаешь. 2. Итерирование по коллекции подразумевает неоднократное чтение из коллекции. Если не обернуть весь цикл в synchronized, то высок шанс словить ConcurrentModificationException, а если обернуть - то оверхед будет значительно серьезней чем в п.1. ConcurrentModificationException - эту ошибку бросают коллекции, если во время итерировани содержимое коллекции было изменено. Такую ошибку можно словить даже в однопоточном приложении, когда не знаешь как работают коллекции.
- Так что ответ на твой последний вопрос - да, это будет потокобезопасно, только лок выдели специальный для этой цели.
- К вопросу о потокобезопасных коллекциях теперь. В java.util.concurrent.* реализовано много многопоточных паттернов, там есть и коллекции. Для большинства случаев лучший из мапов - это ConcurrentHashMap. Его внутренняя структура устроена так, что тебе не нужно синхронизировать доступ. Доступ синхронизируется внутри самой коллекции. Что касается итератора - то при создании итератора коллекция дает тебе срез текущего состояния, и даже если ты будешь удалять какие-то объекты во время итерирования, то это не вызовет ошибки. Самое большое достоинство ConcurrentHashMap в том, что он его внутреннее устройство оптимизирует доступ к коллекции, и ты получаешь минимальный оверхед на любых операциях. платить за это тоже приходится, но это тема другого разговора.
Advertisement
Add Comment
Please, Sign In to add comment