Скачать 0.78 Mb.
|
Часть сообщения Thread[main.5.main] является результатом приведения объекта потока к текстовому формату. В квадратных скобках после ключевого слова Thread соответственно указываются: имя потока, приоритет и группа потока. Для главного потока по умолчанию именем является main, приоритет равен 5, а поток относится к группе с именем main. Имя потока - это его уникальный текстовый идентификатор. Приоритет - целое число. Само значение приоритета особой важности не имеет, важно только, у какого потока оно больше. Приоритет определяет, какому потоку отдается предпочтение при выполнении программы, когда один поток прерывается другим. Поток с низким приоритетом может быть остановлен потоком с более высоким приоритетом. Все потоки разбиваются на группы. Приоритеты потоков сравниваются в пределах групп. Командой t.setName("Самый главный поток") меняется имя главного потока. Новое имя потока "Самый главный поток" указывается аргументом метода setName(), который вызывается из объекта главного потока. Поэтому после выполнения команды Sуstеm.оut.рrintln("После изменения имени: "+t) на экране появляется сообщение: После изменения имени: Тhrеаd[Самый главный поток, 5, mаin] Далее в рамках цикла на экран в столбик выводятся цифры от 5 до 1. При этом использована команда Thread.slеер(1000) для приостановки потока в каждом цикле. В результате выполнения программы получаем: Активный поток: Thread[main, 5, main] После изменения имени: Тhrеаd[Самый главный поток.5,mаin] 5 4 3 2 1 Причем цифровой ряд, выводится на экран с заметной задержкой (порядка одной секунды). Поскольку метод sleep() может выбрасывать исключение InterruptedException (прерывание потока) и это исключение неконтролируемое, то в программе предусмотрена его обработка. В противном случае пришлось бы отразить в сигнатуре метода main() тот факт, что он выбрасывает исключение класса InterruptedExceptiоn. Создание потока Как уже отмечалось, для создания потока (кроме главного) следует либо расширить класс Thread, либо реализовать интерфейс Runnablе. Сначала рассмотрим создание потока путем реализации интерфейса Runnablе. Создать поток можно на базе любого класса, который реализует интерфейс Runnablе. При реализации интерфейса Runnabе достаточно определить всего один метод run(). Программный код этого метода - это тот код, который выполняется в рамках создаваемого потока. Говорят, что метод run() определяет точку входа в поток. Метод run() имеет следующую сигнатуру: public void run() Для начала выполнения потока вызывают метод start(). Общая последовательность действий при создании нового потока путем реализации интерфейса Runnablе следующая. 1. Определяется класс, реализующий интерфейс Runriablе, В этом классе определяется метод run(). 2. В этом классе создается объект класса Thread. Конструктору класса передается два аргумента: объект класса, реализующего интерфейс Runnablе, и текстовая строка – название потока. 3. Для запуска потока из объекта класса Thread вызывается метод start(). Другими словами, для того чтобы определить программный код, выполняемый в новом потоке, необходимо расширить интерфейс Runnаblе, причем указанный код потока - это, фактически, код метода run(), определяемого в классе, расширяющем интерфейс Runnable. Поток в Java - это объект класса Thread. Поэтому для создания потока необходимо создать объект этого класса. В то же время при создании потока необходимо указать код этого потока (то есть код соответствующего метода run()). Код потока определяется в классе, реализующем интерфейс Runnablе. Объект этого класса передается аргументом конструктору класса Thread при создании объекта нового потока. Поскольку создание потока не означает его запуск, поток запускается с помощью метода start(), вызываемого из объекта потока (объект класса Thread). Часто процесс создания нового потока реализуется по следующей схеме. 1. При расширении интерфейса Runnable в соответствующем классе (для удобства назовем его внешним) не только определяется метод run(), но и описывается поле – объект класса Thread. 2. Создание объекта класса Thread (объекта потока), ссылка на который присваивается полю Thread, выполняется в конструкторе внешнего класса. При создании этого объекта вызывается конструктор класса Thread, первым аргументом которому передается ссылка this. Таким образом, одновременно с созданием объекта внешнего класса создается и объект потока, причем объект потока создается на основе объекта внешнего класса. 3. В конструкторе внешнего класса после команды создания объекта потока (объекта класса Thread) из этого потока вызывается метод start(). Это приводит к запуску потока. 4. Для создания и запуска потока в главном методе программы создается объект описанного ранее класса, расширяющего интерфейс Runnablе. Поскольку для запуска потока достаточно самого факта создания объекта, нередко этот создаваемый объект является анонимным, то есть ссылка на него ни в какие объектные переменные не записывается. Пример создания потока на основе реализации интерфейса Runnablе приведен в листинге 2. Листинг 2. Создание потока реализацией интерфейса Runnаblе // Класс, расширяющий интерфейс Runnable: class NewThread implements Runnable{ // Поле – ссылка на объект потока: Thread t; // Конструктор класса: NewThread() { // Создание объекта потока: t=new Тhrеаd(this,"Новый поток"); // Вывод сведений о потоке: Sуstеm.оut.рrintln("Дочерний поток: "+t); t.start(): // Запуск потока } // Определение метода run(): public void run(){ try{ for(int i=5;i>0;i--){ Sуstеm.оut.рrintln("Дочерний поток: "+i); // Приостановка потокa: Thread.sleep(500);} } // Обработка исключительной ситуации прерывания потока catch(InterruptedException е){ Sуstеm.оut.рrintln("Прерывание дочернего потока!");} Sуstеm.оut.рrintln("Завершение дочернего потока!"); } } class ThreadDemo{ public static void main(String args[]){ // Создание анонимного объекта класса NewThread: new NewThread(); // Создание нового потока try{ for(int i=5;i>0;i--){ System.out. println( "Главный поток: "+i*100); // Приостановка главного потока: Thread.sleep(1000);} } // Обработка исключительной ситуации прерывания главного потока: catch(InterruptedException е){ Sуstеm.оut.рrintln("Прерывание главного потока!");} Sуstеm.оut.рrintln("Завершение главного потока!");} } В программе создается класс NewThread, реализующий интерфейс Runnable. Полем этого класса описана переменная t класса Thread.·В конструкторе класса NewThread командой t=new Thread(this."Новый поток") полю t в качестве значения присваивается ссылка на создаваемый объект класса Thread. Объект создается на основе объекта класса NewThread, полем которого является объектная переменная t (первый аргумент конструктора - ключевое слово this), а имя потока задается вторым аргументом конструктора – в данном случае это строка "Новый поток". Командой Sуstеm.оut.рrintln("Дочерний поток: "+t) выводятся сведения о созданном потоке, а командой t.start() поток запускается. Еще раз отметим, что все эти действия описаны в конструкторе класса NewThread, то есть выполняются они при создании объекта этого класса. В классе NеwТhrеаd описан метод run(). Этим методом с интервалом задержки в 0,5 секунды выводится сообщение "Дочерний поток: " и натуральное число от 5 до 1 с шагом дискретности 1. Для приостановки потока использована команда Thread.sleep(500). Кроме того, в методе run() обрабатывается исключение InterruptedException (прерывание потока) для выполняемого потока. В главном методе программы в классе ThreadDemo командой new NewThread() создается анонимный объект класса NewThread, чем автоматически запускается дочерний поток. После этого в рамках главного потока с интервалом задержки в одну секунду выводится сообщение "Главный поток: " и число от 500 до 100 с интервалом дискретности 100. Как и в случае дочернего потока, приостановка главного потока осуществляется вызовом метода sleep(), также отслеживается и обрабатывается исключение InterruptedException. В результате выполнения программы получаем: Дочерний поток: Тhrеаd[Новый поток,5,mаin] Главный поток: 500 Дочерний поток: 5 Дочерний поток: 4 Дочерний поток: 3 Главный поток: 400 Дочерний поток: 2 Дочерний поток: 1 Главный поток: 300 Завершение дочернего потока! Главный поток: 200 Главный поток: 100 Завершение главного потока! Фактически, при выполнении программы накладываются друг на друга два процесса (потока): главным потоком сообщения выводятся с интервалом одна секунда, а дочерним потоком сообщения выводятся с интервалом 0,5 секунды. Поскольку количество выводимых в каждом из потоков сообщений одинаково, а интервал между сообщениями главного потока больше, чем интервал между сообщениями дочернего потока, первым заканчивается дочерний поток, а его сообщения появляются «кучнее». Практически также создаются потоки наследованием класса Thread. Здесь уместно отметить, что класс Thread сам наследует интерфейс Runnable. Поэтому принцип создания потока остается неизменным, просто вместо непосредственной реализации в создаваемом классе интерфейса Runnablе этот интерфейс реализуется опосредованно, путем расширения (наследования) класса Thread. Реализация метода run() в классе Thread не предполагает каких-либо действий. Выход из ситуации можно найти, расширив класс Thread путем создания подкласса. Как и в предыдущем случае с интерфейсом Runnablе, в подклассе, создаваемом на основе класса Thread, необходимо описать (переопределить) метод run() и запустить его унаследованным из Thread методом start(). Правда, здесь есть одно отличие, которое, в принципе, упрощает ситуацию. Дело в том, что при создании объекта подкласса, расширяющего класс Thread, нет необходимости создавать объект класса Thread, как это было в предыдущем примере, когда в реализующем интерфейс Runnablе классе определялось поле-объект класса Thread. Поток вызывается прямо из объекта подкласса. В листинге 3 приведен пример создания нового потока путем расширения класса Thread. Листинг 3. Создание потока расширением класса Thread // Класс NewThread расширяет класс Thread: class NewThread extends Thread{ // Конструктор класса: NewThread(){ // Вызов конструктора класса Thread: super( "Новый поток"); // Вывод сведений о потоке: Sуstеm.оut.рrintln("Дочерний поток: "+this); // Запуск потока на выполнение: start(); } // Переопределение метода run(): public void run(){ try{ for(int i=5;i>0;i--){ Sуstеm.оut.рrintln("Дочерний поток: "+i); // Приостановка потока: Thread.sleep(500);} } // Обработка исключения прерывания потока: catch(InterruptedException е){ Sуstеm.оut.рrintln("Прерывание дочернего потока!");} Sуstеm.оut.рrintln("Завершение дочернего потока!");} } class ExtendsThreadDemo{ public static void main(String args[]){ new NewThread(); try{ for(int i=5;i>0;i--){ Sуstеm.оut.рrintln("Главный поток: "+i*100); Thread.sleep(1000);} }catch(InterruptedException е){ Sуstеm.оut.рrintln("Прерывание главного потока!");} Sуstеm.оut.рrintln("Завершение главного потока!"); } } В результате выполнения программы получаем следующее: Дочерний поток: Тhrеаd[Новый поток, 5, mаin] Главный поток: 500 Дочерний поток: 5 Дочерний поток: 4 Дочерний поток: 3 Главный поток: 400 Дочерний поток: 2 Дочерний поток: 1 Главный поток: 300 Завершение дочернего потока! Главный поток: 200 Главный поток: 100 Завершение главного потока! Программа, фактически, такая же, как и в предыдущем случае. Однако создание потока реализовано по-иному. В классе NewThread, который наследует класс Thread, определяются конструктор и метод run(). В конструкторе командой super("Новый поток") вызывается конструктор класса Thread с аргументом - названием создаваемого потока. Вывод на экран информации о потоке осуществляется командой: Sуstеm.оut.рrintln("Дочерний поток: "+this) Причем здесь в качестве ссылки на объект потока использована ссылка. this на создаваемый объект. Запускается поток вызовом метода start() объекта. Во всем остальном программный код схож с кодом из рассмотренного ранее примера и, думается, особых комментариев не требует. |
Лабораторная работа №9 59 Лабораторная работа №10 72 Лабораторная... Рабочая тетрадь для выполнения лабораторных работ по мдк. 03. 01. «Техническое обслуживание и ремонт компьютерных систем и комплексов»... |
Лабораторная работа 1 4 лабораторная работа 2 13 лабораторная работа... Интернете разнообразную информацию – описательную, графическую, картографическую и пр. При разработке сайтов необходимо уметь работать... |
||
Методические указания для студентов по выполнению лабораторных работ... Лабораторная работа 4, 5 Исследование регистров, счетчиков и дешифраторов Лабораторная работа 6, 7 Исследование генератора псевдослучайной... |
Лабораторная работа №10. Изучение принципа действия и функциональной... Лабораторная работа № Изучение принципов построения системы автоматической подстройки частоты (апч) радиолокационной станции |
||
Лабораторная работа №27 Лабораторная работа №28 Контрольные работы... Пм «Сборка монтаж (демонтаж) элементов судовых конструкций, корпусов, устройств и систем металлических судов» |
Лабораторная работа №1 «Применение средств операционных систем и... |
||
Лабораторная работа №1 «Применение средств операционных систем и... |
Лабораторная работа № Лабораторная работа №1. Изучение основных возможностей программного продукта Яндекс. Сервер. Установка окружения, установка и настройка... |
||
Практическая работа Содержание Лабораторная работа: Оценка программно-аппаратных средств при переходе на Windows Vista 3 |
Лабораторная работа 1 Тема работы: Установка операционной системы.... Оответствии с инструкциями преподавателя, последовательность действий, описанных в частях 1 и 2, может быть скорректирована с учетом... |
||
Лабораторная работа №2. Расчет матрицы a инерционных коэффициентов... Лабораторная работа №3. Расчет матриц Якоби (С7, D7j) исполнительного механизма космического манипуляционного робота 9 |
Контрольная работа №1 по теме «Организм. Молекулярный уровень» Лабораторная работа №2 «Изучение клеток и тканей растений и животных на готовых микропрепаратах» |
||
Лабораторная работа Изучение принципов функционирования простейшей микроэвм и процессора Лабораторная работа Изучение принципов функционирования простейшей микроэвм и процессора I8085A при реализации программы |
Лабораторная работа №5 Тема: Использование элементов управления, cookie, сессии. Работа с почтой Запустите файл из папки лабораторной работы №7 для установки Denver. Внимательной следуйте инструкциям программы – установки. Установку... |
||
Лабораторная работа №4a ... |
Лабораторная работа №1 Целью работы является изучение технологии построения модели процесса в нотации bpmn 0 с использованием |
Поиск |