Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Жизненный цикл потоков. Пример 5.2.4. Как узнать имя потока. Управление потоками. Методы synchronized




Жизненный цикл потоков

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

NEW - поток создан, но еще не запущен;

RUNNABLE - поток выполняется;

BLOCKED - поток блокирован;

WAITING - поток ждет окончания работы другого потока;

TIMEDWAITING - поток некоторое время ждет окончания другого потока;

TERMINATED — поток завершен.

 

Получить значение состояния потока можно вызовом метода getState().

Поток переходит в состояние " неработоспособный" (WAITING) вызовом методов wait(), suspend() (deprecated-метод) или методов ввода/вывода, которые предполагают задержку. Для задержки потока на некоторое время (в миллисекундах) можно перевести его в режим ожидания (TIMEDWAITING) с помощью методов sleep(long millis) и wait(long timeout), при выполнении которого может генерироваться прерывание InterruptedException.

Вернуть потоку работоспособность после вызова метода suspend() можно методом resume () (deprecated-метод), а после вызова метода wait() методами notify() или notifyAll(). Поток переходит в " пассивное" состояние (TERMINATED), если вызваны методы interrupt(), stop() (deprecated метод) или метод run () завершил выполнение. После этого, чтобы запустить поток еще раз, необходимо создать новый объект потока. Метод interrupt() успешно завершает поток, если он находится в состоянии " работоспособный".

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

При разработке не следует использовать методы принудительной остановки потока, так как возможны проблемы с закрытием ресурсов и другими внешними объектами.

Методы suspend(), resume() и stop() являются deprecated-методами и запрещены к использованию, так как они не являются в полной мере «потокобезопасными».  

 

Пример 5. 2. 4. Как узнать имя потока

package threadtest; public class ThreadTest { public static void main(String[] args) {  RunnableExample runnableExample = new RunnableExample();   Thread t1 = new Thread(runnableExample);   Thread t2 = new Thread(runnableExample);   Thread t3 = new Thread(runnableExample);   t1. start();   t2. start();     t3. setName(" Third Thread" );   t3. start(); } } package threadtest; public class RunnableExample implements Runnable { @Override public void run() {  System. out. println(" My Name is: - " + Thread. currentThread(). getName()); }} Вывод может быть таким: My Name is: - Third ThreadMy Name is: - Thread-1My Name is: - Thread-0

Управление потоками

Приостановить (задержать) выполнение потока можно с помощью метода sleep(int millis) класса Thread. Менее надежный альтернативный способ состоит в вызове метода yield(), который может сделать некоторую паузу и позволяет другим потокам начать выполнение своей задачи. Метод join() блокирует работу потока, в котором он вызван, до тех пор, пока не будет закончено выполнение вызывающего метод потока или не истечет время ожидания при обращении к методу join(long timeout). Пример 5. 2. 5. package jointhread; class JoinThread extends Thread { public JoinThread (String name) { super(name); } public void run() { String nameT = getName(); long timeout = 0; System. out. println(" Старт потока " + nameT); try {    switch (nameT) {   case " First": timeout = 5_000;    case " Second": timeout = 1_000; } Thread. sleep(timeout); System. out. println(" завершение потока " + nameT); } catch (InterruptedException e) { e. printStackTrace(); } }}public class JoinRunner { static {    System. out. println(" Старт потока main" );    } public static void main(String[ ] args) { JoinThread t1 = new JoinThread(" First" ); JoinThread t2 = new JoinThread(" Second" );

Методы synchronized

Нередко возникает ситуация, когда несколько потоков имеют доступ к некоторому объекту, проще говоря, пытаются использовать общий ресурс и начинают мешать друг другу. Более того, они могут повредить этот общий ресурс. Например, когда два потока записывают информацию в файл/объект/поток. Для контролирования процесса записи может использоваться разделение ресурса с применением ключевого слова synchronized. В качестве примера будет рассмотрен процесс записи информации в файл двумя конкурирующими потоками. В методе main() классa SynchroRun создаются два потока. В этом же методе создается экземпляр класса Resource, содержащий поле типа FileWriter, связанное с файлом на диске. Экземпляр Resource передается в качестве параметра обоим потокам. Первый поток записывает строку методом writing() в экземпляр класса Resource. Второй поток также пытается сделать запись строки в тот же самый объект Resource. Во избежание одновременной записи такие методы объявляются как synchronized.

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

Пример 5. 2. 6. package synch; import java. io. *; public class Resource { private FileWriter fileWriter;   public Resource (String file) throws IOException { // проверка наличия файла
Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...