import static net.mindview.util.Print.*,
public class DaemonFromFactory implements Runnable { public void run() { try {
while(true) {
TimeUnit MILLISECONDS.sleep(lOO); print(Thread.currentThread() + " " + this);
}
} catch(InterruptedException e) { print("Interrupted");
}
}
public static void main(String[] args) throws Exception {
ExecutorService exec = Executors newCachedThreadPool(
new DaemonThreadFactory()), for(int i = 0; i < 10. i++)
exec.execute(new DaemonFromFactory()); printC'Bce демоны запущены"); TimeUnit MILLISECONDS.sleep(500); // Задержка
}
} /// ~
Каждый статический метод создания ExecutorService перегружается для получения объекта ThreadFactory, который будет использоваться для создания новых потоков.
Сделаем еще один шаг — создадим вспомогательный класс DaemonThread-PoolExecutor:
// net/mi ndvi ew/uti1/DaemonThreadPoolExecutor.java package net mindview.util; import java util.concurrent *;
public class DaemonThreadPoolExecutor extends ThreadPoolExecutor {
public DaemonThreadPoolExecutorО {
super(0, Integer MAX_VALUE. 60L. TimeUnit SECONDS.
new SynchronousQueue
new DaemonThreadFactoryO).
}
} /// ~
Чтобы узнать, какие значения должны передаваться при вызове конструктора базового класса, я просто заглянул в исходный код Executors.java.
Чтобы узнать, является ли поток демоном, вызовите метод isDaemon(). Если поток является демоном, то все потоки, которые он производит, также будут демонами, что и демонстрируется следующим примером:
//: concurrency/Daemons.java
// Потоки, порождаемые демонами, также являются демонами
import java util.concurrent.*,
import static net mindview util Print.*,
class Daemon implements Runnable {
private Thread[] t = new Thread[10]; public void run() {
for(int i = 0; i < t length; i++) {
t[i] = new Thread (new DaemonSpawnO); t[i].startO:
printnb("DaemonSpawn " + i + " started. ");
}
for(int i = 0. i < t.length, i++)
printnb("t[" + i + "]. isDaemonO = " + t[i] isDaemonO + ");
while(true)
Thread.yieldO;
class DaemonSpawn implements Runnable { public void run() { while(true)
Thread.yieldO;
public class Daemons {
public static void main(String[] args) throws Exception { Thread d = new Thread(new DaemonO); d.setDaemon(true); d.startO;
printnbC'd.isDaemonO = " + d.isDaemonO + ". "); // Даем потокам-демонам завершить процесс запуска: TimeUnit.SECONDS.sleep(l);
}
} /* Output:
d.isDaemonO = true, DaemonSpawn 0 started, DaemonSpawn 1 started. DaemonSpawn 2 started. DaemonSpawn 3 started. DaemonSpawn 4 started. DaemonSpawn 5 started. DaemonSpawn 6 started, DaemonSpawn 7 started, DaemonSpawn 8 started. DaemonSpawn 9 started. t[0].isDaemonO = true. t[l] isDaemonO = true, t[2].isDaemonO = true, t[3].isDaemonO = true. t[4].isDaemonO = true. t[5].isDaemonO = true. t[6].isDaemonO = true. t[7].isDaemonO = true. t[8].isDaemonO = true. t[9].isDaemonO = true. *///:-
Поток Daemon переводится в режим демона, а затем порождает группу новых потоков, которые явно не назначаются демонами, но при этом все равно оказываются ими. Затем Daemon входит в бесконечный цикл, на каждом шаге которого вызывается метод yield(), передающий управление другими процессам.