Потоки вообще и в Java

Пото́к выполне́ния (англ. thread) — наименьшая единица обработки, исполнение которой может быть назначено ядром операционной системы.

(www.wikipedia.org)

Поток данных (англ. stream)

в программировании — абстракция, используемая для чтения или записи файлов, сокетов и т. п. в единой манере. (www.wikipedia.org)

Рассмотрим в общих чертах, что такое потоки, для чего и как они работают. Как и чем они используются в Java, и что под этим подразумевается.

Процесс — экземпляр программы , которому выделены системные ресурсы (память, процессор и тд.), выполняется в отдельном адресном пространстве недоступное для других процессов, и соответственно не имеет доступ к структурам другого процесса.

 

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

Потоки для фоновых действий по обслуживанию основных потоков в Java это потоки-демоны

Получается Thread — “подпрограмма”, которая выполняется параллельно с основной программой. С позволяет одновременно выполнять различные программные задачи.

Интересный для нас класс — java.lang.Thread. В этом классе определены все методы, необходимые для создания потоков, управления их состоянием и синхронизации.

Thread позволяет:

  • Создавать свой дочерний класс на базе класса Thread. Переопределив метод run, вы получите метод, работающий в рамках отдельного потока.
  • Реализовывать в классе интерфейс Runnable и определять метод run, который будет работать как отдельный поток.
 

Теперь немного о других потоках. Stream — универсальное представление данных, что позволяет различным программам и устройствам получать и передавать информацию.

В отличии от Thread, который вереница или НИТЬ команд, Stream ПОТОК переносящий информацию от источника к получателю.

Стандартные потоки (Stream) — потоки процесса зарезервированный для выполнения некоторых «стандартных» функций. В Java доступны три стандартных потока, которые всегда открыты .

Стандартный ввод (0) — зарезервирован для чтения команд пользователя или входных данных. При интерактивном запуске программы по умолчанию нацелен на чтение с устройства текстового интерфейса пользователя (клавиатуры).

В Java реализован, как: System.in. Стандартный поток ввода in определен как статический объект класса InputStream, который содержит только простейшие методы для ввода данных.

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

При фоновом режиме обычно переназначают этот поток в файл. System.out — связан с консолью.

Стандартный поток вывода out создан на базе класса PrintStream, предназначенного для форматированного вывода данных в виде текстовой строки.

Стандартный вывод ошибок (2) — зарезервирован для вывода диагностических и отладочных сообщений в текстовом виде. Чаще всего цель этого потока совпадает со стандартным выводом, с отличием в том, что отладочные сообщения процесса, вывод которого перенаправлен, всё равно попадут пользователю.

System.err — стандартный поток вывода сообщений об ошибках err так же, как и стандартный поток вывода out, создан на базе класса PrintStream.

Базовые классы для работы с файлами и потоками Stream

 

Вернемся к потокам процесса (Thread).

Все потоки, созданные процессом, выполняются в адресном пространстве этого процесса и имеют доступ к ресурсам процесса.

Однако поток одного процесса не имеет никакого доступа к ресурсам потока другого процесса, так как они работают в разных адресных пространствах.

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

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

Потоки созданные разными процесса конкурируют за процессорное время. Для управления распределением времени для потоков в Java предусмотрены три значения для приоритетов потоков. Это NORM_PRIORITY, MAX_PRIORITY и MIN_PRIORITY.

По умолчанию вновь поток имеет нормальный приоритет NORM_PRIORITY, потоки с таким приоритетом пользуются процессорным времени на равных правах. MAX_PRIORITY выполняются раньше тех что с нормальным приоритетом, MIN_PRIORITY — после выполнения всех “нормальных” .

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

Стеки (анг. stack, область памяти хранящая хранящая локальные переменные и ссылки на объекты) для параллельных потоков — РАЗЛИЧНЫЕ,

а область кучи (анг. heap, “медленное хранилище” объектов) этих же потоков — ОБЩАЯ, что служит источником дополнительных проблем.

Синхронизация- возможность которая есть в Java, позволяющая синхронизировать не только методы, но и целые блоки программы. Объявление их как synchronized разрешает в один момент времени исполнять данный блок только одному потоку.

Помимо “буквальной” синхронизации, можно скоординировать работу потоков “тонкой” блокировкой потоков: блокировка на заданный период времени, временная приостановка и возобновление работы, ожидание извещения (ожидать, продолжить, всем), ожидание завершения потока .

Важный момент: во избежания переполнения памяти или даже падения программы необходимо закрывать потоки явным образом.

Были использованы материалы взятые из:

  1. www.wikipedia.org
  2. www.helloworld.ru
  3. www.progwards.ru
  4. www.pixbay.com

ShuRuPin, Базовый курс, октябрь 2020