Многопоточность Flashcards
Дайте определение понятию “процесс”.
Процесс — это совокупность кода и данных, разделяющих общее виртуальное адресное пространство. Процессы изолированы друг от друга, поэтому прямой доступ к памяти чужого процесса невозможен (взаимодействие между процессами осуществляется с помощью специальных средств). Для каждого процесса ОС создает так называемое «виртуальное адресное пространство», к которому процесс имеет прямой доступ. Это пространство принадлежит процессу, содержит только его данные и находится в полном его распоряжении. Операционная система же отвечает за то, как виртуальное пространство процесса проецируется на физическую память.
Дайте определение понятию “поток”.
Один поток («нить» или «трэд») – это одна единица исполнения кода. Каждый поток последовательно выполняет инструкции процесса, которому он принадлежит, параллельно с другими потоками этого процесса.
Дайте определение понятию “синхронизация потоков”.
Синхронизация относится к многопоточности. Синхронизированный блок кода может быть выполнен только одним потоком одновременно.Java поддерживает несколько потоков для выполнения. Это может привести к тому, что два или более потока получат доступ к одному и тому же полю или объекту. Синхронизация — это процесс, который позволяет выполнять все параллельные потоки в программе синхронно. Синхронизация позволяет избежать ошибок согласованности памяти, вызванных непоследовательным доступом к общей памяти.
Когда метод объявлен как синхронизированный — нить держит монитор для объекта, метод которого исполняется. Если другой поток выполняет синхронизированный метод, ваш поток заблокируется до тех пор, пока другой поток не отпустит монитор.
Синхронизация достигается в Java использованием зарезервированного слова synchronized. Вы можете использовать его в своих классах определяя синхронизированные методы или блоки. Вы не сможете использовать synchronized в переменных или атрибутах в определении класса.
Как взаимодействуют программы, процессы и потоки?
Чаще всего одна программа состоит из одного процесса, но бывают и исключения (например, браузер Chrome создает отдельный процесс для каждой вкладки, что дает ему некоторые преимущества, вроде независимости вкладок друг от друга). В каждом процессе может быть создано множество потоков. Процессы разделены между собой (>программы), потоки в одном процессе могут взаимодействовать друг с другом (методы wait, notify, join и т.д.).
. В каких случаях целесообразно создавать несколько потоков?
Многопоточные приложения применяются в случаях, когда можно разделить программу на несколько относительно независимых частей. В этом случае чтобы один код не ждал другой их помещают в различные потоки. В качестве примера можно привести программу с графическим интерфейсом — пока выполняются какие-либо длительные вычисления в одном потоке, интерфейс может быть доступен пользователю и не зависать, если он выполняется в другом потоке.
Что может произойти если два потока будут выполнять один и тот же код в программе?
Если используются не синхронизированные данные, то может произойти ситуация, когда код работает уже с устаревшими данными. Например, в первом потоке идет изменение каких-либо полей, а в это время второй поток читает эти поля.
Что вы знаете о главном потоке программы?
Маленькие программы на Java обычно состоят из одной нити, называемой «главной нитью» (main thread). Но программы побольше часто запускают дополнительные нити, их еще называют «дочерними нитями». Главная нить выполняет метод main и завершается. Аналогом такого метода main, для дочерних нитей служит метод run интерфейса Runnable. Много потоков — много методов main (run()).
Какие есть способы создания и запуска потоков?
С помощью класса, реализующего Runnable
С помощью класса, расширяющего Thread
С помощью класса, реализующего java.util.concurrent.Callable
Какой метод запускает поток на выполнение?
Thread.start() запускает дочерний поток. Для интерфейса Callable запуск потока осуществляется с помощью метода submit().
в Каком методе потока описывается код для выполнения ?
Метод run() или метод call() для дочерних потоков. Метод main() для главного потока.
Когда поток завершает свое выполнение?
Поток закончит выполнение, когда завершится его метод run() или call(). Для главного потока это метод main().
Как синхронизировать метод?
Или указать в сигнатуре модификатор synchronized или использовать конструкцию synchronized {} внутри метода.
Как принудительно остановить поток?
В Java 8 нет метода, который бы принудительно останавливал поток. Никто не гарантирует, что нить можно остановить. Она может остановиться только сама. Java имеет встроенный механизм оповещения потока, который называется Interruption (прерывание, вмешательство).
Класс Thread содержит в себе скрытое булево поле, которое называется флагом прерывания. Установить этот флаг можно вызвав метод interrupt() потока. Проверить же, установлен ли этот флаг, можно двумя способами. Первый способ — вызвать метод bool isInterrupted() объекта потока, второй — вызвать статический метод bool Thread.interrupted(). Первый метод возвращает состояние флага прерывания и оставляет этот флаг нетронутым. Второй метод возвращает состояние флага и сбрасывает его. Заметьте что Thread.interrupted() — статический метод класса Thread, и его вызов возвращает значение флага прерывания того потока, из которого он был вызван. Поэтому этот метод вызывается только изнутри потока и позволяет потоку проверить своё состояние прерывания.
У методов, приостанавливающих выполнение потока, таких как sleep(), wait() и join() есть одна особенность — если во время их выполнения будет вызван метод interrupt() этого потока, они, не дожидаясь конца времени ожидания, сгенерируют исключение InterruptedException.
поток-демон”.
Потоками-демонами называются потоки, работающие в фоновом режиме для нашей программы.
В Java процесс завершается тогда, когда завершается последний его поток. Даже если метод main() уже завершился, но еще выполняются порожденные им потоки, система будет ждать их завершения.
Однако это правило не относится к особому виду потоков – демонам. Если завершился последний обычный поток процесса, и остались только потоки-демоны, то они будут принудительно завершены и выполнение процесса закончится. Чаще всего потоки-демоны используются для выполнения фоновых задач, обслуживающих процесс в течение его жизни.
Thread thread = new Thread(new DaemonClass()); thread.setDaemon(true); System.out.println(thread.isDaemon()); //true
Как получить текущий поток?
Thread.currentThread(),
монитор
Несколько нитей могут мешать друг другу при обращении к одним и тем же данным. Для решения этой проблемы придуман мьютекс (он же монитор). Он имеет два состояния — объект занят и объект свободен. Монитор(мьютекс) — высокоуровневый механизм взаимодействия и синхронизации потоков, обеспечивающий доступ к неразделяемым ресурсам.
Когда какой-то нити нужен общий для всех нитей объект, она проверяет мьютекс, связанный с этим объектом. Если мьютекс свободен, то нить блокирует его (помечает как занятый) и начинает использование общего ресурса. После того, как она сделала свои дела, мьютекс разблокируется (помечается как свободен).
Если же нить хочет использовать объект, а мьютекс заблокирован, то нить засыпает в ожидании. Когда мьютекс, наконец, освободится занятой нитью, наша нить тут же заблокирует его и приступит к работе. Мьютекс встроен в класс Object и следовательно он есть у каждого объекта.
Когда одна нить заходит внутрь блока кода, помеченного словом synchronized, то Java-машина тут же блокирует мьютекс у объекта, который указан в круглых скобках после слова synchronized. Больше ни одна нить не сможет зайти в этот блок, пока наша нить его не покинет. Как только наша нить выйдет из блока, помеченного synchronized, то мьютекс тут же автоматически разблокируется и будет свободен для захвата другой нитью. Если же мьютекс был занят, то наша нить будет стоять на месте и ждать когда он освободится.
приостановить выполнение потока?
Thread.sleep()