На этом шаге рассмотрим синхронизацию потоков управления в UML.
Представьте себе многочисленные потоки управления в параллельной системе. Когда поток проходит через некоторую операцию, мы говорим, что эта операция является точкой выполнения. Если операция определена в некотором классе, то можно сказать, что точкой выполнения является конкретный экземпляр этого класса. В одной операции (и, стало быть, в одном объекте) могут одновременно находиться несколько потоков управления, а бывает и так, что разные потоки находятся в разных операциях, но все же в одном объекте.
Проблема возникает тогда, когда в одном объекте находятся сразу несколько потоков управления. Если не проявить осторожность, то более чем один поток может модифицировать один и тот же атрибут, что приведет к некорректному изменению состояния объекта или потере информации. Это классическая проблема взаимного исключения. Ошибки при обработке такой ситуации могут стать причиной различных видов конкуренции между потоками и их взаимной интерференции, что проявляется в сбоях параллельной системы.
Ключ к решению проблемы – сериализация доступа к критическому объекту. У данного подхода есть три разновидности, суть каждой из которых заключается в присоединении к операциям, определенным в классе, некоторых синхронизирующих свойств. UML позволяет моделировать все три возможности:
Некоторые языки программирования поддерживают перечисленные конструкции непосредственно. Так в языке Java есть свойство synchronized, эквивалентное свойству concurrent в UML. В любом языке, поддерживающем параллельность, все три подхода можно реализовать с помощью семафоров (semaphores).
На рис. 1 показано, как эти свойства присоединяются к операции, – путем применения нотации, принятой в UML для ограничений.
Рис.1. Синхронизация
Обратите внимание, что одновременность должна быть объявлена отдельно как для каждой операции, так и для целого объекта. Объявление одновременности для операции означает беспроблемное единовременное выполнение ее многочисленных вызовов. Объявление одновременности для объекта позволяет вызовам разных операций выполняться одновременно и без ошибок.
С помощью ограничений можно моделировать различные вариации примитивов синхронизации. Например, можно модифицировать свойство concurrent, разрешив наличие нескольких читателей, но только одного писателя.
На следующем шаге рассмотрим моделирование множества потоков управления.