Добавил:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
4-1 Мережне програмування / ЛК / Лекция 6 Сетевое программирование - Threads part1.pptx
Скачиваний:
110
Добавлен:
02.02.2021
Размер:
435.66 Кб
Скачать

Асинхронное выполнение

В предыдущей программе (пример про join), вы видели, что основной поток и созданный поток выполняются независимо.

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

Просто выведем имя потока и текущую итерацию цикла

Асинхронное выполнение

В результате нескольких запусков нашего кода можно получить например такое:

 

 

Один запуск программы:

 

 

 

 

 

Другой запуск программы:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Видно, что вывод для этих двух запусков программы немного отличается. Почему? Thread-0 и Thread-1 выполняются независимо. Вывод не фиксирован и порядок выполнения итераций в потоках, не предсказуем. Программист не может определить порядок выполнения потоков.

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

Вы не можете ни прогнозировать, ни контролировать очередность выполнения потоков!

Нужно быть аккуратными при программировании многопоточных приложений и принимать во внимание эту особенность.

Потоки-демоны

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

С помощью метода setDaemon(boolean value), вызванного вновь созданным потоком до его запуска, можно определить поток-демон.

Метод boolean isDaemon() позволяет определить, является ли указанный поток демоном или нет.

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

Потоки-демоны

Пример:

Результат работы при sleep(10000) :

Результат работы при sleep(1) :

Поток-демон (из-за вызова sleep(10000)) не успел завер- шить выполнение своего кода до завершения основного потока приложения, связанного с методом main().

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

Базовые состояния потока

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

Программа может получить доступ к состоянию потока которое описывается перечислением Thread.State. В классе Thread имеется экземплярный метод getState(), который возвращает текущее состояние потока:

Каждый поток в Java проходит через эти три состояния:

NEW

Старт потока

RUNNABLE

Поток завершил задачи

TERMINATED

Вывод на консоль:

Совет: Осторожно используйте информацию о состоянии потоков при помощи метода getState(). Почему? - К тому времени когда вы получили и используете информацию о состоянии потоков, это состояние могло измениться…

Два состояния работающего потока в ОС

Когда поток поменял состояние с NEW на RUNNABLE, на уровне ОС он может быть в одном из двух состояниях:

ready (готовность)running (выполняется)

Состояние ready означает, что поток ожидает от ОС выполнения на процессоре. Если поток выполняется процессором, его состояние в ОС running.

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

 

ОС диспетчеризирует

ready

поток

running

 

таймаут

Когда использовать потоки

Типовое приложение с многопоточностью выполняет длительные вычисления в фоновом режиме. Главный поток продолжает выполнение, в то время как рабочий поток выполняет фоновую задачу. В оконных приложениях ОС Windows, когда главный поток занят длительными вычислениями, он не может обрабатывать сообщения клавиатуры и мыши, и приложение перестает откликаться. По этой причине следует запускать отнимающие много времени задачи в рабочем потоке, даже если главный поток в это время демонстрирует пользователю модальный диалог с надписью “Работаю...

Пожалуйста, ждите”, так как программа не может перейти к следующей операции, пока не закончена текущая. Т.о .приложение не будет помечено ОС как “Не отвечающее”.

В случае приложений без UI, например, различных служб, многопоточность имеет смысл, если выполняемая задача может занять много времени, так как требуется ожидание ответа от другого компьютера (сервера приложений, сервера баз данных или клиента). Запуск такой задачи в отдельном рабочем потоке означает, что главный поток немедленно освобождается для других задач.

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

Недостатки многопоточности:

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

2.Чрезмерное использование многопоточности отнимает ресурсы и время CPU на создание потоков и переключение между потоками.

Вопросы ?

Соседние файлы в папке ЛК