Синхронизированный (vector<vector>) блокирует все Векторы или только тот, который их хранит?
Скажем, у меня есть несколько векторов: v1, v2, v3
Скажем, у меня также есть вектор, который содержит эти vList = {v1, v2, v3}
Если я синхронизировался (vList), означает ли это, что v1, v2 и v3 также заблокированы или это просто блокировка vList?
3 ответа
Синхронизированный не блокирует объекты! Это отмечает критический раздел кода.
Если вы используете его для метода (synchronized void foo()
) только один поток может получить доступ к этому методу.
Если вы используете его с объектом (synchronized(bar)
) только поток из-за блокировки этого объекта может войти в критическую зону.
Это означает, что для синхронизации по 'bar' требуется, чтобы каждый поток, который хочет войти в эту зону (или любой другой синхронизированный по 'bar'), запросил блокировку. Если они не получают его, они блокируются, пока Поток, владеющий блокировкой, не освободит его.
Это означает, что если все ваши векторы работают только в блоке, синхронизированном по одной переменной, этого обычно достаточно.
Синхронизация в нескольких объектах подряд также не проблема:
synchronized(bar){..} synchronized(foo){..}
Там, где это сложно, это каскадные синхронизации, так как это может привести к тупикам:
synchronized(bar){
synchronized(foo){..}
}
И последнее но не менее важное:
Вам не нужно блокировать Vector, чтобы сделать его сохраненным, так как каждый метод vector определяется с помощью synchronized
(Как видно здесь). Вам нужно установить дополнительную блокировку, только если вы хотите редактировать несколько векторов без вмешательства других потоков.
Вам решать, что защищает замок. Если вы решите, что он блокирует все три из них, то он блокирует все три из них. Просто отразите это решение во всем коде, который обращается к этим объектам.
Отношения между замками и объектами - это концепция дизайна кода, которая должна быть отражена во всем коде, который имеет дело с заблокированными объектами. Чтобы избежать условий гонки и других ошибок, программисты могут использовать блокировку для защиты объекта. Мы говорим, что блокировка "X" блокирует объект "Y", если мы намереваемся, чтобы все обращения к объекту "Y" выполнялись, удерживая блокировку "X". Поскольку только один поток может одновременно удерживать блокировку "X", это правило гарантирует, что только один поток одновременно обращается к объекту "Y". Замок не знает и не заботится о том, какие объекты он защищает.
Если весь код, обращающийся к "v1", удерживает блокировку "vList" при обращении к нему, то "vList" блокирует "v1". Если есть некоторый код, который обращается к "v1" без удержания блокировки "vList", "vList" не блокирует "v1".
Каждый Vector<T>
делает свой собственный контент поточно-ориентированным:
Vector<Vector<T>>
блокирует вектор векторов, но не отдельные векторы- Каждый человек
Vector<T>
внутри он запирает векторT
сам.
Другими словами, если вы получите два вектора T
из вашего вектора векторов и передавая эти векторы различным потокам, вы сможете получить доступ к векторам одновременно, без блокировки потоков друг с другом.
С другой стороны, если вы начнете получать доступ к вектору векторов одновременно, доступ будет взаимоисключающим, поскольку вектор синхронизирован.