Как глубоко блокировка идет?

Java, конечно, развивался очень медленно - особенно при сравнении его с C# и VB. Я лично чувствую, что они приняли неправильное решение с дженериками с точки зрения хранения обратной совместимости за счет безопасности времени выполнения и эффективности. Подход.NET работает намного лучше в [почти 111] каждый путь, IMO.

Java 7 имеет длинный список потенциал функции - и язык и платформа - но это было ужасно долгое время в процессе создания, и существуют все еще значительные вопросительные знаки по многим функциям.

я не хотел бы возлагать любую "вину" на то, почему это произошло, как бы то ни было.

10
задан Dark Star1 4 September 2012 в 17:53
поделиться

7 ответов

Оператор блокировки НЕ является «кодом блокировки» или каким-либо ресурсом, который находится между фигурными скобками.

Я считаю, что лучше всего понимать блокировку с точки зрения потока (в конце концов, сценарии потоковой передачи - это когда вам необходимо рассмотреть возможность блокировки.

Учитывая ваш пример кода

10  locker = new object();
11  lock (locker)
12  {
     ...
15  }

Когда поток X достигает строки 10, создается новый объект, а в строке 11 устанавливается блокировка объекта. Поток X продолжает выполнять любой код внутри блока.

Теперь, когда поток X находится в середине нашего блока, поток Y достигает строки 10. И вот, создается новый объект, и, поскольку он создан потоком Y, в настоящее время для этого объекта не используется блокировка. Таким образом, когда поток Y достигает 11, он успешно получает блокировку объекта и продолжает выполнять блок одновременно с потоком X.

Это ситуация, которую блокировка должна была предотвратить. Так что делать? Сделайте шкафчик общим объектом .

01  static object locker = new object();

    ...

11  lock (locker)
12  {
     ...
15  }

Теперь, когда поток X достигает строки 11, он получает блокировку и начинает выполнение блока. Когда поток Y достигает строки 11, он попытается получить блокировку того же объекта, что и поток X. Поскольку этот объект уже заблокирован, поток Y будет ждать, пока блокировка не будет снята. Таким образом предотвращается одновременное выполнение блока кода, тем самым защищая любые ресурсы, используемые этим кодом, для одновременного доступа.

Примечание: если другие части вашей системы должны быть сериализованы вокруг одних и тех же ресурсов, все они должны попытаться заблокировать один и тот же общий шкафчик объект.

12
ответ дан 3 December 2019 в 16:10
поделиться

Блокировка влияет только на код в теле инструкции блокировки. Объекты, переданные в качестве параметра, действуют как уникальный идентификатор, на него не влияют никакие внутренние факторы.

4
ответ дан 3 December 2019 в 16:10
поделиться

Это очень просто - замок блокирует код внутри замка заявление. Если вы используете эти ресурсы в другом месте своего кода, они не будут охвачены этой блокировкой.

Некоторые классы имеют механизмы на них, поэтому вы можете заблокировать их в нескольких местах - примером этого является свойство Syncroot Hashtable. . Однако полезность этого сомнительна . Хорошее обсуждение этого вопроса находится на SO .

Лучше всего инкапсулировать эту логику в отдельный класс с внутренним механизмом блокировки и убедиться, что ваше приложение использует только этот класс.

3
ответ дан 3 December 2019 в 16:10
поделиться

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

Вы также можете проверить ответы на этот вопрос: Блокирует ли lock () {} ресурс,или он блокирует фрагмент кода?

2
ответ дан 3 December 2019 в 16:10
поделиться

Блокировка не относится к какому-либо объекту - она ​​относится только к фрагменту кода. Итак, если у вас есть две разные функции, которые работают с глобальным сокетом, вы должны контролировать их обе, в вашем примере это должен быть один и тот же объект «шкафчик» - так что сделайте его видимым для обоих фрагментов кода.

1
ответ дан 3 December 2019 в 16:10
поделиться

Краткий ответ: Нет

Блокировка - это логическая концепция, а не физическая, когда язык / ЦП определяет объем блокировки и ограничивает доступ ко всем элементам в этой области. Ваша задача - принудительно использовать блокировку, поэтому, если вам нужно получить блокировку X для использования ресурса Y, вы должны убедиться, что вы всегда это делаете.

1
ответ дан 3 December 2019 в 16:10
поделиться

Фактически, как только вы назначаете им идентификатор, они становятся общедоступной переменной-членом данного элемента. Так, например, если у вас есть

<mx:Canvas><mx:Label id="myLabel" /></mx:Canvas>

, вы можете получить к нему доступ по его id в качестве имени переменной:

myLabel.text = "Hello world!";

Дайте мне знать, если вам нужны дополнительные разъяснения. Если это не то, о чем вы спрашиваете, не стесняйтесь комментировать, и я сделаю еще один удар.

С уважением,

  • блокировка - это логическая концепция.
  • блокировка блокирует только то, что находится в блоке кода в фигурных скобках.

Но чтобы дать вам краткое представление:

блокировка - не что иное, как замена Monitor.Enter и Monitor.Exit . Только это с блокировкой Monitor.Exit помещается в блок finally.

Итак, то, что вы ДЕЙСТВИТЕЛЬНО блокируете (в вашем коде), является объектом шкафчика. Итак, в любом месте вашего кода, если вы используете этот объект-шкафчик для блокировки, этот блок кода будет заблокирован.

Я предполагаю, что ваша блокировка работает так: (гуру, пожалуйста, поправьте меня, если я ошибаюсь)

if(locker.SyncBlockIndex <0)>                                                       
{                                                                                
//obtain an index to free synch cache block                                      
//assign the index obtained in previous step to obj.SyncBlockIndex               
}                                                                                
syncblock = syncblockCache[locker.SyncBlockIndex]                                   
if(!syncblock is owned by the calling thread)                                    
{                                                                                
//susped the calling thread                                                      
}            

Посмотрите, поможет ли вам эта ссылка разобраться в блокировке (я написал этот пост когда-то назад)

http://dotenetscribbles.blogspot.com/2008/10/calling-monitorenter-recursively. html

3
ответ дан 3 December 2019 в 16:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: