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

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

Жанры

Философия 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,

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

Вкус ледяного поцелуя

Полякова Татьяна Викторовна
2. Ольга Рязанцева
Детективы:
криминальные детективы
9.08
рейтинг книги
Вкус ледяного поцелуя

Проблема майора Багирова

Майер Кристина
1. Спецназ
Любовные романы:
современные любовные романы
6.60
рейтинг книги
Проблема майора Багирова

Прометей: владыка моря

Рави Ивар
5. Прометей
Фантастика:
фэнтези
5.97
рейтинг книги
Прометей: владыка моря

Попаданка в академии драконов 4

Свадьбина Любовь
4. Попаданка в академии драконов
Любовные романы:
любовно-фантастические романы
7.47
рейтинг книги
Попаданка в академии драконов 4

(Не)зачёт, Дарья Сергеевна!

Рам Янка
8. Самбисты
Любовные романы:
современные любовные романы
5.00
рейтинг книги
(Не)зачёт, Дарья Сергеевна!

Запасная дочь

Зика Натаэль
Фантастика:
фэнтези
6.40
рейтинг книги
Запасная дочь

Дракон с подарком

Суббота Светлана
3. Королевская академия Драко
Любовные романы:
любовно-фантастические романы
6.62
рейтинг книги
Дракон с подарком

Отвергнутая невеста генерала драконов

Лунёва Мария
5. Генералы драконов
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Отвергнутая невеста генерала драконов

Случайная жена для лорда Дракона

Волконская Оксана
Фантастика:
юмористическая фантастика
попаданцы
5.00
рейтинг книги
Случайная жена для лорда Дракона

Тройняшки не по плану. Идеальный генофонд

Лесневская Вероника
Роковые подмены
Любовные романы:
современные любовные романы
6.80
рейтинг книги
Тройняшки не по плану. Идеальный генофонд

Идеальный мир для Лекаря 28

Сапфир Олег
28. Лекарь
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Идеальный мир для Лекаря 28

Лейтенант космического флота

Борчанинов Геннадий
1. Звезды на погонах
Фантастика:
боевая фантастика
космическая фантастика
космоопера
рпг
фэнтези
фантастика: прочее
5.00
рейтинг книги
Лейтенант космического флота

Гарем на шагоходе. Том 5

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

Матабар III

Клеванский Кирилл Сергеевич
3. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар III