logo
Методичка Java

Преимущества и проблемы при работе с потоками выполнения

Почему бывают нужны потоки выполнения? Представьте себе программу управления спектрометром, в которой одно табло должно показывать время, прошедшее с начала измерений, второе – число импульсов со счётчика установки, третье – длину волны, для которой в данный момент идут измерения. Кроме того, в фоновом режиме должен отрисовываться получающийся после обработки данных спектр. Возможны две идеологии работы программы – последовательная и параллельная. При последовательном подходе во время выполнения алгоритмов, связанных с показом информации на экране, следует время от времени проверять, не пришли ли новые импульсы со счётчиков, и не надо ли установить спектрометр на очередную длину волны. Кроме того, во время обработки данных и отрисовки спектра следует через определённые промежутки обновлять табло времени и счётчиков.

В результате код программы перестаёт быть структурным. Нарушается принцип инкапсуляции – “независимые вещи должны быть независимы”. Независимые по логике решаемой проблемы алгоритмы оказываются перемешаны друг с другом. Такой код оказывается ненадёжным и плохо модифицируемым. Однако он относительно легко отлаживается, поскольку последовательность выполнения операторов программы однозначно определена.

В параллельном варианте для каждого из независимых алгоритмов запускается свой поток выполнения, и ему задаётся необходимый приоритет. В нашем случае один (или более) поток занимается измерениями. Второй – показывает время, прошедшее с начала измерений, третий – число импульсов со счётчика, четвёртый – длину волны. Пятый поток рисует спектр. Каждый из них занят своим делом и не вмешивается в другой. Связь между потоками идёт только через данные, которые первый поток поставляет остальным.

Несмотря на изящество параллельной модели, у неё имеются очень неприятные недостатки.

Во-первых, негарантированное время отклика. Например, при использовании потоков для анимации графических объектов может наблюдался сбой равномерности движения объекта.

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