Чтение онлайн

на главную

Жанры

Java: руководство для начинающих
Шрифт:

Удалите следующую строку кода: Thread thrd; Переменная thrd уже не нужна, поскольку класс MyThread включает в себя экземпляр класса Thread и может ссылаться на самого себя.

Внесите в конструктор класса Thread следующие изменения: // построить новый поток. MyThread(String name) { super(name); // присвоить потоку имя start; // начать поток } Как видите, в данном конструкторе присутствует ключевое слово super, которое используется для вызова следующего варианта конструктора Thread: Thread(String имя); где имя обозначает присваиваемое потоку конкретное имя.

Внесите приведенные ниже изменения в метод run , чтобы он вызывал метод getName непосредственно, не предваряя его именем переменной thrd. // начать исполнение нового метода public void run { System.out.println(getName + " starting."); try { for(int count=0; count < 10; count++) { Thread.sleep(400); System.out.println("In " + getName + ", count is " + count); } } catch(InterruptedException exc) { System.out.println(getName + " interrupted."); } System.out.println(getName + " terminating."); }

Ниже

приведен весь исходный код программы, в которой вместо реализации интерфейса Runnable используется подкласс, производный от класса Thread. Выполнение этой программы дает такой же результат, как и предыдущие ее версии. /* Пример для опробования 11.1. Расширение класса Thread. */ class MyThread extends Thread { // построить новый поток MyThread(String name) { super(name); // присвоить потоку имя start ; // начать поток } // начать исполнение нового потока public void run { System.out.println(getName + " starting."); try { for(int count=0; count < 10; count++) { Thread.sleep(400); System.out.println("In " + getName + ", count is " + count); } } catch(InterruptedException exc) { System.out.println(getName + " interrupted."); } System.out.println(getName + " terminating."); } } class ExtendThread { public static void main(String args[]) { System.out.println("Main thread starting."); MyThread mt = new MyThread("Child #1"); for(int i=0; i < 50; i++) { System.out.print("."); try { Thread.sleep(100); } catch(InterruptedException exc) { System.out.println("Main thread interrupted."); } } System.out.println("Main thread ending."); } } Создание нескольких потоков

В предыдущем примере был создан только один порожденный поток. Но в программе можно породить столько потоков, сколько требуется. Например, в приведенной ниже программе формируются три порожденных потока. // Создание нескольких потоков. class MyThread implements Runnable { Thread thrd; // построить новый поток MyThread(String name) { thrd = new Thread(this, name); thrd.start; // начать поток } // начать исполнение нового потока public void run { System.out.println(thrd.getName + " starting."); try { for(int count=0; count < 10; count++) { Thread.sleep(400); System.out.println("In " + thrd.getName + ", count is " + count); } } catch(InterruptedException exc) { System.out.println(thrd.getName + " interrupted."); } System.out.println(thrd.getName + " terminating."); } } class MoreThreads { public static void main(String args[]) { System.out.println("Main thread starting."); // Создание и запуск на исполнение трех потоков. MyThread mtl = new MyThread("Child #1"); MyThread mt2 = new MyThread("Child #2"); MyThread mt3 = new MyThread("Child #3"); for (int i=0; i < 50; i++) { System.out.print("."); try { Thread.sleep(100); } catch(InterruptedException exc) { System.out.println("Main thread interrupted."); } } System.out.println("Main thread ending."); } }

Ниже приведен результат выполнения данной программы. Main thread starting. Child #1 starting. .Child #2 starting. Child #3 starting. ...In Child #3, count is О In Child #2, count is 0 In Child #1, count is 0 ....In Child #1, count is 1 In Child #2, count is 1 In Child #3, count is 1 ....In Child #2, count is 2 In Child #3, count is 2 In Child #1, count is 2 ...In Child #1, count is 3 In Child #2, count is 3 In Child #3, count is 3 ....In Child #1, count is 4 In Child #3, count is 4 In Child #2, count is 4 ....In Child #1, count is 5 In Child #3, count is 5 In Child #2, count is 5 ...In Child #3, count is 6 .In Child #2, count is 6 In Child #1, count is 6 ...In Child #3, count is 7 In Child #1, count is 7 In Child #2, count is 7 ....In Child #2, count is 8 In Child #1, count is 8 In Child #3, count is 8 ....In Child #1, count is 9 Child #1 terminating. In Child #2, count is 9 Child #2 terminating. In Child #3, count is 9 Child #3 terminating. Main thread ending.

Как видите, после запуска на исполнение все три потока совместно используют ресурсы ЦП. Следует иметь в виду, что потоки в данном примере запускаются на исполнение в том порядке, в каком они были созданы. Но так происходит не всегда. Исполняющая система Java сама планирует исполнение потоков. Вследствие отличий в вычислительных средах у вас может получиться несколько иной результат. Определение момента завершения потока

Нередко

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

Правда, в классе Thread предусмотрены два средства, позволяющие определить, завершился ли поток. Первым из них является метод is Alive , объявление которого приведено ниже. final boolean isAlive

Этот метод возвращает логическое значение true, если поток, для которого он вызывается, все еще исполняется. В противном случае он возвращает логическое значение false. Для того чтобы опробовать метод isAlive на практике, замените в предыдущей программе класс MoreThreads новой версией, исходный код которой приведен ниже. // Применение метода isAlive. class MoreThreads { public static void main(String args[]) { System.out.println("Main thread starting."); MyThread mtl = new MyThread("Child #1"); MyThread mt2 = new MyThread("Child #2"); MyThread mt3 = new MyThread("Child #3"); do { System.out.print(" . ") ; try { Thread.sleep(100); } catch(InterruptedException exc) { System.out.println("Main thread interrupted."); } // Ожидание завершения потоков. } while (mtl.thrd.isAlive || mt2.thrd.isAlive || mt3.thrd.isAlive); System.out.println("Main thread ending."); } }

Эта версия дает такой же результат, как и предыдущая. Единственное отличие состоит в том, что в данном случае ожидание завершения порожденного потока организовано с помощью метода isAlive . Вторым средством, позволяющим определить, завершился ли поток, является метод join , объявление которого приведено ниже. final void join throws InterruptedException

Этот метод ожидает завершения потока, для которого он был вызван. Его имя join выбрано потому, что вызывающий поток ожидает, когда указанный поток присоединится (англ.уши) к нему. Имеется и другой вариант метода j oin , позволяющий указать максимальное время ожидания момента, когда поток завершится.

В приведенном ниже примере программы наличие метода join гарантирует, что основной поток завершит работу последним. // Применение метода join. class MyThread implements Runnable { Thread thrd; // построить новый поток MyThread(String name) { thrd = new Thread(this, name); thrd.start; // начать поток } // начать исполнение нового потока public void run { System.out.println(thrd.getName + " starting."); try { for(int count=0; count < 10; count++) { Thread.sleep(400); System.out.println("In " + thrd.getName + ", count is " + count); } } catch(InterruptedException exc) { System.out.println(thrd.getName + " interrupted."); } System.out.println(thrd.getName + " terminating."); } } class JoinThreads { public static void main(String args[]) { System.out.println("Main thread starting."); MyThread mtl = new MyThread("Child #1"); MyThread mt2 = new MyThread("Child #2"); MyThread mt3 = new MyThread("Child #3"); try { // Ожидание до тех nop, пока указанный метод не завершится. mtl.thrd.join; System.out.println("Child #1 joined."); mt2.thrd.join ; System.out.println("Child #2 joined."); mt3.thrd.join; System.out.println("Child #3 joined."); } catch(InterruptedException exc) { System.out.println("Main thread interrupted."); } System.out.println("Main thread ending."); } }

Результат выполнения данной программы приведен ниже. Вследствие отличий в вычислительных средах он может получиться у вас несколько иным. Main thread starting. Child #1 starting. Child #2 starting. Child #3 starting. In Child #2, count is 0 In Child #1, count is 0 In Child #3, count is 0 In Child #2, count is 1 In Child #3, count is 1 In Child #1, count is 1 In Child #2, count is 2 In Child #1, count is 2 In Child #3, count is 2 In Child #2, count is 3 In Child #3, count is 3 In Child#1, count is 3 In Child #3, count is 4 In Child #2, count is 4 In Child #1, count is 4 In Child #3, count is 5 In Child #1, count is 5 In Child #2, count is 5 In Child #3, count is 6 In Child #2, count is 6 In Child #1, count is 6 In Child #3, count is 7 In Child #1, count is 7 In Child #2, count is 7 In Child #3, count is 8 In Child #2, count is 8 In Child #1, count is 8 In Child #3, count is 9 Child #3 terminating. In Child #2, count is 9 Child #2 terminating. In Child #1, count is 9 Child #1 terminating. Child #1 joined. Child #2 joined. Child #3 joined. Main thread ending.

Поделиться:
Популярные книги

Лорд Системы 8

Токсик Саша
8. Лорд Системы
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Лорд Системы 8

Осознание. Пятый пояс

Игнатов Михаил Павлович
14. Путь
Фантастика:
героическая фантастика
5.00
рейтинг книги
Осознание. Пятый пояс

Академия

Кондакова Анна
2. Клан Волка
Фантастика:
боевая фантастика
5.40
рейтинг книги
Академия

Князь Мещерский

Дроздов Анатолий Федорович
3. Зауряд-врач
Фантастика:
альтернативная история
8.35
рейтинг книги
Князь Мещерский

Огненный князь 5

Машуков Тимур
5. Багряный восход
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Огненный князь 5

Новый Рал 4

Северный Лис
4. Рал!
Фантастика:
попаданцы
5.00
рейтинг книги
Новый Рал 4

Варлорд

Астахов Евгений Евгеньевич
3. Сопряжение
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Варлорд

Пропала, или Как влюбить в себя жену

Юнина Наталья
2. Исцели меня
Любовные романы:
современные любовные романы
6.70
рейтинг книги
Пропала, или Как влюбить в себя жену

Инкарнатор

Прокофьев Роман Юрьевич
1. Стеллар
Фантастика:
боевая фантастика
рпг
7.30
рейтинг книги
Инкарнатор

Жена на пробу, или Хозяйка проклятого замка

Васина Илана
Фантастика:
попаданцы
фэнтези
5.00
рейтинг книги
Жена на пробу, или Хозяйка проклятого замка

Холодный ветер перемен

Иванов Дмитрий
7. Девяностые
Фантастика:
попаданцы
альтернативная история
6.80
рейтинг книги
Холодный ветер перемен

Корпулентные достоинства, или Знатный переполох. Дилогия

Цвик Катерина Александровна
Фантастика:
юмористическая фантастика
7.53
рейтинг книги
Корпулентные достоинства, или Знатный переполох. Дилогия

Приручитель женщин-монстров. Том 5

Дорничев Дмитрий
5. Покемоны? Какие покемоны?
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Приручитель женщин-монстров. Том 5

Довлатов. Сонный лекарь

Голд Джон
1. Не вывожу
Фантастика:
альтернативная история
аниме
5.00
рейтинг книги
Довлатов. Сонный лекарь