Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Turning an ExecutorService to daemon in Java

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.

like image 476
Antiz Avatar asked Dec 14 '12 17:12

Antiz


People also ask

How do I stop being an ExecutorService?

To properly shut down an ExecutorService, we have the shutdown() and shutdownNow() APIs. The shutdown() method doesn't cause immediate destruction of the ExecutorService. It will make the ExecutorService stop accepting new tasks and shut down after all running threads finish their current work: executorService.

How would you create a daemon in Java?

The setDaemon() method of the Thread class is used to mark/set a particular thread as either a daemon thread or a user thread. The Java Virtual Machine exits when the only threads running are all daemon threads.

How do I reuse ExecutorService?

You can reuse the executor service if you restructure your code somewhat. Basically you collect all your tasks, execute them, and await execution before proceeding. Of course, you could also alternatively just use a new Executor Service for each of your time steps, but at least you have options.

Should ExecutorService be shutdown?

When finished using an ExecutorService , you need to shut it down explicitly. From its javadoc: "An unused ExecutorService should be shut down to allow reclamation of its resources." Calling shutdown initiates a gradual and orderly shutdown.


2 Answers

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();         }     } }); 
like image 61
Pshemo Avatar answered Oct 28 '22 00:10

Pshemo


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.

like image 42
Marco13 Avatar answered Oct 28 '22 02:10

Marco13