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

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

Жанры

Философия Java3

Эккель Брюс

Шрифт:

private volatile double d; // Без оптимизации продолжение &

private int priority; public SimplePriorities(int priority) { this.priority = priority;

}

public String toStringO {

return Thread.currentThreadО + "; " + countDown;

}

public void runО {

Thread.currentThreadO.setPriority(priority); while(true) {

// Высокозатратная, прерываемая операция; for(int 1=1: i < 100000; i++) {

d += (Math.PI + Math.E) / (double)i; ifCi % 1000 == 0)

Thread.yieldO;

}

System.out.printin(this); if(--countDown == 0) return;

}

}

public static void main(String[] args) {

ExecutorService exec = Executors.newCachedThreadPoolО; for(int i = 0; i < 5; i++) exec.execute(

new SimplePriorities(Thread.MIN_PRIORITY));

exec.execute(

new SimplePriorities(Thread.MAX_PRIORITY)); exec.shutdownO;

}

} /* Output:

Thread[pool-l-thread-6.10.main]: 5 ThreadEpool-l-thread-6.10.main]: 4 ThreadEpool-l-thread-6.10.main]: 3 ThreadEpool-l-thread-6.10.main]: 2 ThreadEpool-l-thread-6.10.main]: 1 ThreadEpool-l-thread-3.1.main]: 5 ThreadEpool-l-thread-2.1.main]: 5 ThreadEpool-1-thread-l.1.main]: 5 ThreadEpool-l-thread-5.1.main]: 5 ThreadEpool-l-thread-4.1.main]: 5

*///:-

В этой версии метод toStringO переопределяется и использует метод Thread. toString, который выводит имя потока (его можно задать в конструкторе, но здесь имена автоматически генерируются в виде pool-1-thread-l, pool-l-thread-2 и т. д.), приоритет и группу, к которой принадлежит поток. Переопределенная версия toString также выводит обратный отсчет, выполняемый задачей. Обратите внимание: для получения ссылки на объект Thread, управляющий задачей, внутри самой задачи, следует вызвать метод Thread.currentThreadO.

Мы видим, что приоритет последнего потока имеет наивысший уровень, а все остальные потоки находятся на низшем уровне. Учтите, что приоритет задается в начале выполнения run; задавать его в конструкторе бессмысленно, потому что Executor в этот момент еще не начал выполнять задачу.

В метод run были добавлены 100 ООО достаточно затратных операций с плавающей запятой, включая суммирование и деление с числом двойной точности double. Переменная d была отмечена как volatile, чтобы компилятор не применял оптимизацию. Без этих вычислений вы не увидите эффекта установки различных приоритетов (попробуйте закомментировать цикл for с вычислениями). В процессе вычислений мы видим, что планировщик уделяет больше внимания потоку с приоритетом MAX_PRI0RITY (по крайней мере, таково было поведение программы на машине под управлением Windows ХР). Несмотря даже на то, что вывод на консоль также является «дорогостоящей» операцией, с ним вы не увидите влияние уровней приоритетов, поскольку вывод на консоль не прерывается (иначе экран был бы заполнен несуразицей), в то время как математические вычисления, приведенные выше, прерывать допустимо. Вычисления выполняются достаточно долго, соответственно, механизм планирования потоков вмешивается в процесс и чередует потоки, проявляя при этом внимание к более приоритетным. Тем не менее для обеспечения переключения контекста в программе периодически выполняются команды yield.

В пакете JDK предусмотрено 10 уровней приоритетов, однако это не слишком хорошо согласуется с большинством операционных систем. К примеру, в Windows имеется 7 классов приоритетов, таким образом, их соотношение неочевидно (хотя в операционной системе Sun Solaris имеется 231 уровней). Переносимость обеспечивается толх^о использованием универсальных констант МАХ_РRIORITY, NORM.PRIORITY и MIN_PRI0RITY.

Передача управления

Если вы знаете, что в текущей итерации run сделано все необходимое, вы можете подсказать механизму планирования потоков, что процессором теперь может воспользоваться другой поток. Эта подсказка (не более чем рекомендация; нет никакой гарантии, что планировщик потоков «прислушается» к ней) воплощается в форме вызова метода yield. Вызывая yield, вы сообщаете системе, что в ней могут выполняться другие потоки того же приоритета.

В примере LiftOff метод yield обеспечивает равномерное распределение вычислительных ресурсов между задачами LiftOff. Попробуйте закомментировать вызов Thread.yield в Lift0ff.run и проследите за различиями. И все же, в общем случае не стоит полагаться на yield как на серьезное средство настройки вашего приложения.

Потоки-демоны

Демоном называется поток, предоставляющий некоторый сервис, работая в фоновом режиме во время выполнения программы, но при этом не является ее неотъемлемой частью. Таким образом, когда все потоки не-демоны заканчивают свою деятельность, программа завершается. И наоборот, если существуют работающие потоки не-демоны, программа продолжает выполнение. Существует, например, поток не-демон, выполняющий метод main.

//: concurrency/SimpleDaemons.java

// Потоки-демоны не препятствуют завершению работы программы

import java.util.concurrent.*.

import static net mindview.util.Print.*;

public class SimpleDaemons implements Runnable { public void run { try {

while(true) {

TimeUni t.MILLISECONDS.sieep(100). print(Thread.currentThread + " H + this);

}

} catch(InterruptedException e) {

printC'sleepO interrupted").

}

}

public static void main(String[] args) throws Exception { for(int i = 0. i < 10; i++) {

Thread daemon = new Thread(new SimpleDaemonsO).

daemon setDaemon(true); // Необходимо вызвать перед startO

daemon. startO;

}

printCBce демоны запущены"). TimeUnit.MILLISECONDS sleep(175);

}

} /* Output: Все демоны запущены

Thread[Thread-0.5.main] SimpleDaemons@530daa Thread[Thread-1.5.main] SimpleDaemons@a62fc3 Thread[Thread-2.5.main] SimpleDaemons@89ae9e Thread[Thread-3,5,main] SimpleDaemons@1270b73 Thread[Thread-4.5.main] SimpleDaemons@60aeb0 Thread[Thread-5.5.main] SimpleDaemons@16caf43 Thread[Thread-6.5.main] SimpleDaemons@66848c Thread[Thread-7.5.main] SimpleDaemons@8813f2 Thread[Thread-8.5.main] SimpleDaemons@ld58aae Thread[Thread-9.5.main] SimpleDaemons@83cc67

*///:-

Чтобы назначить поток демоном, следует перед его запуском вызвать метод setDaemon.

После того как main завершит свою работу, ничто не препятствует завершению программы, поскольку в процессе не работают другие потоки, кроме демонов. Чтобы результаты запуска всех потоков-демонов были более наглядными, поток main на некоторое время погружается в «сон». Без этого вы увидели бы только часть результатов при создании демонов. (Поэкспериментируйте с вызовом sleep для интервалов разной продолжительности.)

В примере SimpleDaemons.java используется явное создание объектов Thread для установки их «демонского» флага. Вы также можете настроить атрибуты (демон, приоритет, имя) потоков, созданных исполнителем; для этого следует написать пользовательскую реализацию ThreadFactory:

//: net/mi ndvi ew/uti1/DaemonThreadFactory.java package net.mindview.util;

import java util.concurrent.*;

public class DaemonThreadFactory implements ThreadFactory { public Thread newThread(Runnable r) { Thread t = new Thread(r), t.setDaemon(true); return t,

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

Личный аптекарь императора. Том 3

Карелин Сергей Витальевич
3. Личный аптекарь императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Личный аптекарь императора. Том 3

На границе империй. Том 10. Часть 10

INDIGO
Вселенная EVE Online
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 10. Часть 10

Вернувшийся: Первые шаги. Том II

Vector
2. Вернувшийся
Фантастика:
боевая фантастика
космическая фантастика
рпг
5.00
рейтинг книги
Вернувшийся: Первые шаги. Том II

Глава рода

Шелег Дмитрий Витальевич
5. Живой лёд
Фантастика:
боевая фантастика
6.55
рейтинг книги
Глава рода

Мачеха Золушки - попаданка

Максонова Мария
Фантастика:
попаданцы
сказочная фантастика
фэнтези
5.00
рейтинг книги
Мачеха Золушки - попаданка

Сирийский рубеж 2

Дорин Михаил
6. Рубеж
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Сирийский рубеж 2

Законник Российской Империи. Том 4

Ткачев Андрей Юрьевич
4. Словом и делом
Фантастика:
городское фэнтези
альтернативная история
аниме
дорама
5.00
рейтинг книги
Законник Российской Империи. Том 4

Старый, но крепкий 7

Крынов Макс
7. Культивация без насилия
Фантастика:
рпг
уся
фэнтези
5.00
рейтинг книги
Старый, но крепкий 7

Здравствуй, 1985-й

Иванов Дмитрий
2. Девяностые
Фантастика:
альтернативная история
5.25
рейтинг книги
Здравствуй, 1985-й

Бастард

Майерс Александр
1. Династия
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард

Вернувшийся: Корпорация. Том III

Vector
3. Вернувшийся
Фантастика:
космическая фантастика
боевая фантастика
рпг
5.00
рейтинг книги
Вернувшийся: Корпорация. Том III

Последний Паладин. Том 2

Саваровский Роман
2. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 2

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

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

Надуй щеки! Том 6

Вишневский Сергей Викторович
6. Чеболь за партой
Фантастика:
попаданцы
дорама
5.00
рейтинг книги
Надуй щеки! Том 6