Главная » Java, Структуры данных и алгоритмы » Подпроцессы Java*

0

Многопоточность является способом организации ограниченного способа параллельной обработки (мультипрограммирования) даже при использовании компьютера с одним процессором. Применение такого механизма дает возможность исполнять несколько задач или подпроцессов одновременно, причем каждый подпроцесс обеспечивает свою часть вычислений. Мультипрограммирование используется в графических приложениях. Например, один подпроцесс может следить за щелчками мыши, а другие — за перемещением частей картинок на экране. Даже при наличии в компьютере только одного процессора все эти подпроцессы могут выполняться практически одновременно благодаря тому, что:

1)            процессор работает с огромной скоростью с точки зрения обычного восприятия времени,

2)            для выполнения каждого подпроцесса операционная система выделяет определенный период времени.

Указанные периоды настолько быстро следуют один за другим, что создается впечатление одновременности выполнения различных подпроцессов.

В Java встроен механизм обеспечения мультипрограммирования — Java-подпроцессы. Подпроцессы представляют собой вычислительные объекты, которые могут взаимодействовать друг с другом для совместного использования различных объектов памяти, экрана компьютера и других видов ресурсов и устройств. Переключение между различными подпроцессами происходит очень быстро, так как для каждого подпроцесса в памяти виртуальной машины Java существует свой Java-стек. Для каждого подпроцесса Java-стек содержит локальные переменные и фреймы методов, выполняемых подпроцессом в текущий момент. Таким образом, чтобы переключиться от одного подпроцесса Г к другому подпроцессу U,

процессору достаточно «запомнить» этап, на котором он вышел из подпроцесса Гперед переключением на подпроцесс U. Выше рассматривался способ реализации этого способа. В частности, путем сохранения текущего значения счетчика программы Т, содержащего ссылку на следующую команду Т, находящуюся в конце Java-стека Т. Сохраняя значения счетчика каждого активного подпроцесса на вершине его Java-стека, процессор затем может вернуться к месту выхода из него и перейти к другому подпроцессу Uпутем записи значения счетчика программы на место значения, записанного на вершине Java-creKa для U(и используя стек Uв качестве «текущего» Java-стека).

Подпроцессы в Java могут находиться в одном из следующих состояний:

•     новый,

•     выполняемый,

•     заблокированный,

•     мертвый.

В момент создания подпроцесс является новым и остается в этом состоянии до тех пор, пока создавший его подпроцесс не отправит ему сообщение start. После запуска подпроцесс становится выполняемым, что означает его готовность к выполнению вычислений при выделении периода времени процессора. Команды подпроцесса начинают исполняться, когда он становится активным. Эти команды могут содержать простейшие или особые операции, которые переводят подпроцесс в заблокированное состояние, то есть он перестает быть выполняемым (до тех пор, пока специальное событие или подпроцесс не вернет его в выполняемое состояние). Операции блокирования включают обращения к методам sleep, suspend или wait, а также прочие команды, которые приостанавливают подпроцесс в ожидании определенного действия входного или выходного потока. В выполняемое состояние подпроцесс возвращается после окончания события, вызвавшего его «засыпание» (то есть он «просыпается»), либо после получения от другого подпроцесса сообщения resume или notify, либо после поступления ожидаемого входного или выходного потока данных. В заключение, когда подпроцесс выполнил все предназначенные действия, он становится мертвым.

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

В некоторых операционных системах существует механизм предотвращения монополизации процессора. При этом для выделения времени процессора всем выполняемым подпроцессам в циклическом протоколе используется очередь. Основная идея такого протокола состоит в том, что все выполняемые подпроцессы хранятся в очереди Q. Когда процессор

готов к исполнению определенного подпроцесса, выполняется операция dequeue для перехода к следующему доступному подпроцессу, назовем его Г. Однако перед тем как процессор начнет выполнять команды Г, запускается таймер, который учитывает время, выделенное для выполнения подпроцесса. После этого процессор ожидает, (а) пока подпроцесс Т заблокирует себя (с помощью одного из перечисленных выше методов блокировки) или (б) истечет отведенное время. Во втором случае процессор прекращает выполнение Т и выполняет операцию enqueue, которая помещает Т в конец цепочки выполняемых в настоящее время подпроцессов. В обоих случаях процессор сохраняет текущее значение счетчика программы Г на вершине Java-creKa для Т и выполняет следующий доступный выполняемый подпроцесс, извлекая его из Q с помощью операции dequeue. Таким образом обеспечивается равное количество времени для выполнения каждого подпроцесса. То есть с помощью очереди и таймера операционная система решает проблему монополизации процессора.

Использование очереди позволяет решить проблему мультипрограммирования, но представленная модель является очень упрощенной Схемой протокола, используемого в большинстве операционных систем, применяющих циклический механизм временных интервалов, так как во многих случаях наряду с этим используется и система приоритета подпроцессов. Другими словами, используется очередь по приоритету для выделения процессорного времени. Приоритетные очереди рассматриваются в главе 7.

Источник: Гудрич М.Т. Г93 Структуры данных и алгоритмы в Java / М.Т. Гудрич, Р. Тамассия; Пер. с англ. A.M. Чернухо. — Мн.: Новое знание, 2003. — 671 е.: ил.

По теме:

  • Комментарии