Ce n'est pas exactement répondre à la question qui nous occupe, mais cela peut s'avérer utile :
Comme d'autres l'ont fait remarquer, vous pouvez créer une DaemonThreadFactory, soit en ligne, soit en tant que classe utilitaire.
En sous-classant Runnable, vous pouvez obtenir le DaemonThread résultant de la Factory ci-dessus pour exécuter l'unité runnable entière dans un Thread non-daemon spawné séparément. Dans des circonstances normales, ce Thread non-daemon se terminera même si le Daemon Thread utilisé dans l'Executor est destiné à être fermé.
Voici un petit exemple :
import static java.util.concurrent.TimeUnit.*;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.*;
public class ScheduleStackOverflow {
private static final DateTimeFormatter DTF_HH_MM_SS = DateTimeFormatter.ofPattern("HH:mm:ss.SSS");
private static final class ThreadRunnable implements Runnable {
private final Runnable runnable;
public ThreadRunnable(final Runnable runnable) {
this.runnable = runnable;
}
@Override
public void run() {
final Thread delegateThread = new Thread(this.runnable);
/**/ delegateThread.setDaemon(false); // TODO Try changing this to "true"
/**/ delegateThread.start();
}
}
public static void main(final String[] args) throws InterruptedException {
final ThreadFactory daemonThreadFactory = (daemonRunnable) -> {
final Thread daemon = new Thread (daemonRunnable);
/**/ daemon.setDaemon(true);
return daemon;
};
final Runnable runnable = new ThreadRunnable(() -> {
System.out.println(DTF_HH_MM_SS.format(LocalTime.now()) + " daemon=" + Thread.currentThread().isDaemon() + " Scheduling...");
sleep(5, SECONDS);
System.out.println(DTF_HH_MM_SS.format(LocalTime.now()) + " daemon=" + Thread.currentThread().isDaemon() + " Schedule done.");
});
Executors
.newSingleThreadScheduledExecutor(daemonThreadFactory)
.scheduleAtFixedRate(runnable, 0, Duration.ofSeconds(10).toNanos(), NANOSECONDS);
sleep(12, SECONDS);
System.out.println(DTF_HH_MM_SS.format(LocalTime.now()) + " Main CLOSED!");
}
private static void sleep(final long timeout, final TimeUnit timeunit) {
try {timeunit.sleep(timeout);} catch (InterruptedException e) {}
}
}