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

на главную - закладки

Жанры

Философия Java3

Эккель Брюс

Шрифт:

public ThreadMethodCString name) { this.name = name; } public void runTaskO { if(t == null) {

t = new Thread(name) {

public void run { try {

while(true) {

print(this);

if(--countDown == 0) return; sleep(lO);

}

} catchdnterruptedException e) {

printCsleepO interrupted");

}

}

public String toStringO {

return getNameO + ": " + countDown;

}

}:

t.startO;

}

}

}

public class ThreadVariations {

public static void main(String[] args) { new InnerThreadlCInnerThreadl") ; new InnerThread2("InnerThread2"); new InnerRunnablelCInnerRunnablel");

new InnerRunnable2("InnerRunnable2"); продолжение &

new ThreadMethodC'ThreadMethod") runTaskO,

}

} ///-

InnerThreadl определяет именованный внутренний класс, производный от Thread, и создает экземпляр этого класса в конструкторе. Поступать так стоит в том случае, когда у внутреннего класса есть особые возможности (новые методы), которые могут понадобиться в других методах. Однако в большинстве случаев причина создания потока — использование функциональности класса Thread, поэтому в именованном внутреннем классе особой нужды нет. Inner-Thread2 показывает другое решение. В конструкторе создается безымянный внутренний субкласс Thread, преобразуемый восходящим преобразованием к ссылке на Thread t. Если другим методам класса понадобится обратиться к t, они смогут сделать это через интерфейс Thread, и им не нужно будет знать точный тип объекта.

Третий и четвертый классы примера повторяют первые два, только вместо класса Thread они используют интерфейс Runnable.

Класс ThreadMethod демонстрирует создание потока в методе. Вы вызываете метод, когда программа готова к запуску потока, а метод возвращает управление после запуска потока. Если поток выполняет только вспомогательные операции и не является фундаментальной частью класса, то этот способ, вероятно, удобнее и практичнее запуска потока из конструктора класса.

Присоединение к потоку

Любой поток может вызвать метод join, чтобы дождаться завершения другого потока перед своим продолжением. Если поток вызывает t.join для другого потока t, то вызывающий поток приостанавливается до тех пор, пока целевой поток t не завершит свою работу (когда метод t.isAlive вернет значение false).

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

Вызов join может быть прерван вызовом метода interrupt для потока-инициатора, поэтому потребуется блок try-catch.

Все эти операции продемонстрированы в следующем примере:

// concurrency/Joining java

// Демонстрация joinO.

import static net mindview util Print *;

class Sleeper extends Thread {

private int duration,

public Sleeper(String name, int sleepTime) { super(name), duration = sleepTime, startO,

}

public void run О {

try {

sleep(duration), } catchdnterruptedException e) {

print(getName + " прерван " +

"isInterruptedO• " + islnterrupted),

return;

}

print(getName + " активизировался"),

}

}

class Joiner extends Thread { private Sleeper sleeper, public Joiner(String name. Sleeper sleeper) { super(name), this.sleeper = sleeper. startO;

}

public void runO { try {

sleeper joinO; } catchdnterruptedException e) { print("Прерван");

}

print (getNameO + " join завершен");

public class Joining {

public static void main(String[] args) { Sleeper

sleepy = new Sleeper("Sleepy". 1500), grumpy = new SIeeper("Grumpy". 1500).

Joiner

dopey = new Joiner("Dopey", sleepy), doc = new Joiner("Doc", grumpy); grumpy interruptO;

}

} /* Output-

Grumpy был прерван. isInterruptedO. false Doc join завершен Sleepy активизировался Dopey join завершен *///;-

Класс Sleeper — это тип потока, который приостанавливается на время, указанное в его конструкторе. В методе run вызов метода sleep может закончиться по истечении времени задержки, но может и прерваться. В секции catch выводится сообщение о прерывании, вместе со значением, возвращаемым методом islnterrupted. Когда другой поток вызывает interrupt для данного потока, устанавливается флаг, показывающий, что поток был прерван. Однако этот флаг сбрасывается при обработке исключения, поэтому внутри секции catch результатом всегда будет false. Флаг используется в других ситуациях, где поток может исследовать свое прерванное состояние в стороне от исключения.

Joiner — поток, который ожидает пробуждения потока Sleeper, вызывая для последнего метод join. В методе main каждому объекту Joiner сопоставляется Sleeper, и вы можете видеть в результатах работы программы, что, если Sleeper был прерван или завершился нормально, Joiner прекращает работу вместе с потоком Sleeper.

Совместное использование ресурсов

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

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

Некорректный доступ к ресурсам

Рассмотрим следующий пример, в котором одна задача генерирует четные числа, а другие задачи эти числа потребляют. Единственной задачей задач-потребите-лей является проверка четности этих чисел.

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

Кодекс Крови. Книга ХIII

Борзых М.
13. РОС: Кодекс Крови
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Крови. Книга ХIII

Законы Рода. Том 7

Андрей Мельник
7. Граф Берестьев
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Законы Рода. Том 7

Двойник Короля 10

Скабер Артемий
10. Двойник Короля
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Двойник Короля 10

Развод. Без права на ошибку

Ярина Диана
Любовные романы:
современные любовные романы
короткие любовные романы
5.00
рейтинг книги
Развод. Без права на ошибку

Купеческая дочь замуж не желает

Шах Ольга
Фантастика:
фэнтези
6.89
рейтинг книги
Купеческая дочь замуж не желает

Симфония теней

Злобин Михаил
3. Хроники геноцида
Фантастика:
попаданцы
фэнтези
5.00
рейтинг книги
Симфония теней

Газлайтер. Том 22

Володин Григорий Григорьевич
22. История Телепата
Фантастика:
боевая фантастика
попаданцы
фэнтези
5.00
рейтинг книги
Газлайтер. Том 22

Возмутитель спокойствия

Владимиров Денис
1. Глэрд
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Возмутитель спокойствия

Наследник хочет в отпуск

Тарс Элиан
5. Десять Принцев Российской Империи
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Наследник хочет в отпуск

Неудержимый. Книга XXXII

Боярский Андрей
32. Неудержимый
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Неудержимый. Книга XXXII

Спасите меня, Кацураги-сан! Том 12

Аржанов Алексей
12. Токийский лекарь
Фантастика:
попаданцы
дорама
фэнтези
5.00
рейтинг книги
Спасите меня, Кацураги-сан! Том 12

Шайтан Иван 4

Тен Эдуард
4. Шайтан Иван
Фантастика:
попаданцы
альтернативная история
8.00
рейтинг книги
Шайтан Иван 4

Офицер Красной Армии

Поселягин Владимир Геннадьевич
2. Командир Красной Армии
Фантастика:
попаданцы
8.51
рейтинг книги
Офицер Красной Армии

Размышления русского боксёра в токийской академии Тамагава, 2

Афанасьев Семён
2. Размышления русского боксёра в токийской академии
Фантастика:
альтернативная история
5.80
рейтинг книги
Размышления русского боксёра в токийской академии Тамагава, 2