96

I am using an ExecutoreService in Java 1.6, started simply by

ExecutorService pool = Executors.newFixedThreadPool(THREADS). 

When my main thread is finished (along with all the tasks processed by the thread pool), this pool will prevent my program from shutting down until I explicitly call

pool.shutdown();

Can I avoid having to call this by somehow turning the internal thread managing used by this pool into a deamon thread? Or am I missing something here.

isapir
  • 21,295
  • 13
  • 115
  • 116
Antiz
  • 1,424
  • 1
  • 13
  • 20
  • 1
    I as author of currently accepted answer would suggest reading approach posted by Marco13: http://stackoverflow.com/a/29453160/1393766 and changing acceptance mark from my post to his, since solution described there is probably simplest and closes to what you originally wanted to achieve. – Pshemo Apr 05 '15 at 02:14
  • 1
    @Pshemo Let me disagree with you... Please check my comment under Marco13's answer. – AlexW Apr 07 '15 at 07:31
  • @Pshemo In view of Vladimirs hint, you might consider pointing out the fact that the "simple" solution may not always be the preferred one. – Marco13 Apr 08 '15 at 11:16
  • @Marco13 I placed "probably" at start of my answer for exactly that reason. But it may be good idea to add in your answer more info about idea behind it, and maybe some general advices like what could be reasonable value of `keepAliveTime` depending on how often tasks are executed. – Pshemo Apr 08 '15 at 11:52

9 Answers9

125

Probably simplest and preferred solution is in Marco13's answer so don't get fooled by vote difference (this answer is few years older) or acceptance mark (it just means that this solution was appropriate for OP circumstances, not that it is best in general).


You can use ThreadFactory to set threads inside Executor to daemons. This will affect executor service in a way that it will also become daemon thread so it (and threads handled by it) will stop if there will be no other non-daemon thread. Here is simple example:

ExecutorService exec = Executors.newFixedThreadPool(4,
        new ThreadFactory() {
            public Thread newThread(Runnable r) {
                Thread t = Executors.defaultThreadFactory().newThread(r);
                t.setDaemon(true);
                return t;
            }
        });

exec.execute(YourTaskNowWillBeDaemon);

But if you want to get executor which will let its task finish, and at the same time will automatically call its shutdown() method when application is complete, you may want to wrap your executor with Guava's MoreExecutors.getExitingExecutorService.

ExecutorService exec = MoreExecutors.getExitingExecutorService(
        (ThreadPoolExecutor) Executors.newFixedThreadPool(4), 
        100_000, TimeUnit.DAYS//period after which executor will be automatically closed
                             //I assume that 100_000 days is enough to simulate infinity
);
//exec.execute(YourTask);
exec.execute(() -> {
    for (int i = 0; i < 3; i++) {
        System.out.println("daemon");
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
});
Pshemo
  • 122,468
  • 25
  • 185
  • 269
  • 1
    Even though this answer was accepted, I don't think this is what OP intended: I think the program should shut down when all tasks have been processed. When setting the executors' thread to 'daemon', the program will exit even when there's still tasks to be ran. – Arnout Engelen Apr 04 '15 at 22:25
  • @ArnoutEngelen I updated my answer to give alternative approach which solves also this problem but I believe that [Marco13's post](http://stackoverflow.com/a/29453160/1393766) contains best approach. – Pshemo Apr 05 '15 at 02:17
61

There already is a built-in functionality for creating an ExecutorService that terminates all threads after a certain period of inactivity: You can create a ThreadPoolExecutor, pass it the desired timing information, and then call allowCoreThreadTimeout(true) on this executor service:

/**
 * Creates an executor service with a fixed pool size, that will time 
 * out after a certain period of inactivity.
 * 
 * @param poolSize The core- and maximum pool size
 * @param keepAliveTime The keep alive time
 * @param timeUnit The time unit
 * @return The executor service
 */
public static ExecutorService createFixedTimeoutExecutorService(
    int poolSize, long keepAliveTime, TimeUnit timeUnit)
{
    ThreadPoolExecutor e = 
        new ThreadPoolExecutor(poolSize, poolSize,
            keepAliveTime, timeUnit, new LinkedBlockingQueue<Runnable>());
    e.allowCoreThreadTimeOut(true);
    return e;
}

EDIT Referring to the remarks in the comments: Note that this thread pool executor will not automatically shut down when the application exits. The executor will continue to run after the application exits, but no longer than the keepAliveTime. If, depending on the precise application requirements, the keepAliveTime has to be longer than a few seconds, the solution in the answer by Pshemo may be more appropriate: When the threads are set to be daemon threads, then they will end immediately when the application exits.

Community
  • 1
  • 1
Marco13
  • 53,703
  • 9
  • 80
  • 159
  • 1
    That is very interesting information. +1. So if I understand it correctly we can simply make Executor free thread resources faster, including also core ones. But just lack of resources doesn't mean that executor will be shutdown when last resource will be removed. Shutdown will be called automatically when Executor will have no resources (and new tasks to run) and application is complete. – Pshemo Apr 05 '15 at 01:59
  • 1
    @Pshemo Yes, this is not a "shutdown" in the sense as in the `shutdown` method. I reworded this a bit, hopefully it's less ambiguous now. – Marco13 Apr 05 '15 at 02:02
  • @Pshemo Thanks for your generosity. That's a lot of attention for the hint to call a single method ;-) – Marco13 Apr 06 '15 at 11:54
  • I am here on Stack Overflow to find exactly this kind of answers: simple, precise but at the same time not very obvious (at least for me). I wish I could show my generosity more often :) – Pshemo Apr 06 '15 at 12:38
  • 3
    @Marco13 This is a interesting feature, I didn't know it, but I don't think I solves a problem properly. Let's assume someone create an _ExecutorService_ using your method and submit some *task* to it, and then the `main()` method finishes. After the *task* is done, _ExecutorService_ will live for _keepAliveTime_, waiting until all core threads die. That means, when you try to stop your java app gracefully, you need to wait some (potentially large) amount of time. I do not think it's good. @Pshemo I believe your answer is the best currently. – AlexW Apr 07 '15 at 07:23
  • 1
    @VladimirS. You're right. Whether or not this behavior is acceptable may also depend on the application pattern. Usually, I give them a `keepAliveTime` of a few seconds (and admittedly, can hardly imagine when a time *greater* than a few seconds would be appropriate or even necessary). If it is required to have a larger `keepAliveTime` and still exit immediately, the daemon thread solution would be preferable. – Marco13 Apr 07 '15 at 08:44
  • 1
    @Marco13 Yes, you are also right, it's a question of app requirements. In my turn, I can not imagine how one can use an `ExecutorService` with `allowCoreThreadTimeOut(true)` and `keepAliveTime` small enough to let it die more or less quickly. What's the benefit of such `ExecutorService`? After small period of inactivity all core threads will die, and a submitting a new task will lead to a new thread creation, with all its overhead, so my task will not start immediately. It will not be a _pool_ anymore. – AlexW Apr 07 '15 at 08:56
  • @VladimirS. This discussion (although interesting) may be beyond the scope of some comments. But I think that in many cases (except for special, highly performance-critical applications), the overhead of the thread creation is negligible, and the main purpose of the `ExecutorService` is not "pooling threads", but offering a *service* in terms of task execution, scheduling, `Future`s etc. But there may be applications where the pooling is more important. One could say that the executor service sketched above is a `cachedExecutorService` with a limited number of threads. – Marco13 Apr 07 '15 at 09:07
  • @Marco13 I see your point, agree. I might be biased a little by working on FX trading app with all its performance-related implications :) – AlexW Apr 07 '15 at 09:19
  • I wonder what's the difference between allowing core thread to timeout and just setting core threads to `0`. – lapo Aug 29 '17 at 07:48
  • @lapo When the work queue is empty, having a `corePoolSize>0`, means that there will always be a thread waiting for new tasks. For `==0`, passing in a new tasks may then always cause the creation of a *new* thread. Regarding the usage and behavior, the difference may not be so important. (Although starting a new thread may be "expensive", compared to just waking up an existing one, the difference will hardly be noticable in almost all application cases) – Marco13 Aug 29 '17 at 12:56
  • @Marco13 oh, I see: with `core>0` but with core-timeout enabled, they get constantly killed and re-created (when idle), but that way the thread is "ready" when the job arrives. I probably prefer to avoid that, but it depends on the use-case. – lapo Aug 29 '17 at 15:00
  • @Marco13 This can also be achieved by modifying the `ThreadPoolExecutor` returned by `newFixedThreadPool`. Have a look at my [answer](https://stackoverflow.com/a/52247367/3595685). – Steve Sep 09 '18 at 18:20
28

I would use Guava's ThreadFactoryBuilder class.

ExecutorService threadPool = Executors.newFixedThreadPool(THREADS, new ThreadFactoryBuilder().setDaemon(true).build());

If you're not already using Guava, I'd go with a ThreadFactory subclass like described at the top of Pshemo's answer

Community
  • 1
  • 1
Phil Hayward
  • 1,113
  • 12
  • 10
  • 1
    Can you explain what is the difference between approach from your answer and the accepted answer? From what I checked in source code of ThreadFactoryBuilder it will create ThreadFactory with with exact same behaviour as presented in mine answer. Did I miss something or point of your answer was to show that with Guava we can shorten this code a little? BTW I am not saying your answer is wrong, I am just trying to understand it better. – Pshemo Apr 08 '15 at 16:54
  • 5
    It's more concise. If you're already using Guava, why rewrite code that exists in the library? You're correct that it does exactly the same thing. – Phil Hayward Apr 08 '15 at 17:16
11

If you only want to use it in one place, then you can inline the java.util.concurrent.ThreadFactory implementation, e.g. for a pool with 4 threads you would write (example shown as a lambda assuming Java 1.8 or newer):

ExecutorService pool = Executors.newFixedThreadPool(4,
        (Runnable r) -> {
            Thread t = new Thread(r);
            t.setDaemon(true);
            return t;
        }
);

But I usually want all of my Thread factories to produce daemon threads, so I add a utility class as follows:

import java.util.concurrent.ThreadFactory;

public class DaemonThreadFactory implements ThreadFactory {

    public final static ThreadFactory instance = 
                    new DaemonThreadFactory();

    @Override
    public Thread newThread(Runnable r) {
        Thread t = new Thread(r);
        t.setDaemon(true);
        return t;
    }
}

That allows me to easily pass DaemonThreadFactory.instance to the ExecutorService, e.g.

ExecutorService pool = Executors.newFixedThreadPool(
    4, DaemonThreadFactory.instance
);

or use it to easily start a daemon Thread from a Runnable, e.g.

DaemonThreadFactory.instance.newThread(
    () -> { doSomething(); }
).start();
isapir
  • 21,295
  • 13
  • 115
  • 116
4

Yes.

You simply need to create your own ThreadFactory class that creates daemon threads rather than regular threads.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
0

This solution is similar to @Marco13's but instead of creating our own ThreadPoolExecutor, we can modify the one returned by Executors#newFixedThreadPool(int nThreads). Here's how:

ExecutorService ex = Executors.newFixedThreadPool(nThreads);
 if(ex instanceof ThreadPoolExecutor){
    ThreadPoolExecutor tp = (ThreadPoolExecutor) ex;
    tp.setKeepAliveTime(time, timeUnit);
    tp.allowCoreThreadTimeOut(true);
}
Steve
  • 889
  • 1
  • 12
  • 26
  • 1
    A nitpick here is: You cannot be sure that `newFixedThreadPool` will return a `ThreadPoolExecutor`. (It does, and almost certainly will, forever, but you do not *know* that) – Marco13 Sep 09 '18 at 18:26
0

You can use Guava's ThreadFactoryBuilder. I didn't want to add the dependency and I wanted the functionality from Executors.DefaultThreadFactory, so I used composition:

class DaemonThreadFactory implements ThreadFactory {
    final ThreadFactory delegate;

    DaemonThreadFactory() {
        this(Executors.defaultThreadFactory());
    }

    DaemonThreadFactory(ThreadFactory delegate) {
        this.delegate = delegate;
    }

    @Override
    public Thread newThread(Runnable r) {
        Thread thread = delegate.newThread(r);
        thread.setDaemon(true);
        return thread;
    }
}
etherous
  • 709
  • 4
  • 10
0

This doesn't exactly answer the question in hand, but it may prove useful:

As others have commented, you can create a DaemonThreadFactory, either inline or as a utility class.

By subclassing Runnable, you can get the resulting DaemonThread from the above Factory to perform the entire runnable unit within a separately spawned non-daemon Thread. Under normal circumstances this non-daemon Thread will complete even though the Daemon Thread used in the Executor is earmarked to be closed.

Here's a little example:

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) {}
    }
}
Dave The Dane
  • 650
  • 1
  • 7
  • 18
-1

If you have a known list of tasks, you don't need daemon threads at all. You can simply call shutdown() on the ExecutorService after submitting all your tasks.

When your main thread is complete, use the awaitTermination() method to allow time for the submitted tasks to complete.The currently submitted tasks will be executed, and the thread pool will terminate its control thread once they have been completed.

for (Runnable task : tasks) {
  threadPool.submit(task);
}
threadPool.shutdown();
/*... do other stuff ...*/
//All done, ready to exit
while (!threadPool.isTerminated()) {
  //this can throw InterruptedException, you'll need to decide how to deal with that.
  threadPool.awaitTermination(1,TimeUnit.SECOND); 
}
Phil Hayward
  • 1,113
  • 12
  • 10
  • 1
    This strategy will not interrupt/stop tasks that follow a 'run until interrupted' pattern, in which the threads will continue to run (since they are not daemon and not interrupted). Much safer to set threads to daemon if it's important to actually stop them. – Krease Jun 23 '16 at 17:13