Returning from java method before all threads are done

Jessica :

Is it possible to return from a java method that started threads before all the threads are done?

Here's my code:

import java.util.concurrent.*;

public class ExecutorSample {
    public static void main(String[] args) {
        ExecutorService service = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            service.execute(() -> {
                while (true) {
                }
            });
        }
        return;
    }
}

This doesn't return for some reason that I don't understand. Why is the main thread's return affected by the worker threads being stuck?

yshavit :

Your main method is returning, but the problem is that your JVM isn't exiting. You can test this by renaming your main method to something else, like doMain(), and then writing main as:

public static void main(String[] args) {
    doMain();
    System.out.printf("here");
}

You'll see that you do get the output, but the program doesn't end.

What's happening is that Executors.newCachedThreadPool uses the default thread factory, which creates non-daemon threads. When your main method returns, the JVM will wait for all non-daemon threads to finish (that's what differentiates them from daemon threads -- the JVM doesn't wait for those). Since all of your Runnables run forever, the non-daemon threads will never finish, and the JVM will never exit.

What can you do? Some options:

  • Use the overload newCachedThreadPool(ThreadFactory), supplying a ThreadFactory that creates daemon threads
  • Use shutdownNow() on your ExecutorService. That will send an interrupt on each of the running threads. You'll still have to check for that on each thread, either by calling a method that throws InterruptedException or by explicitly calling Thread.currentThread().isInterrupted().

For the shutdownNow approach, note that interrupting a thread by itself is not enough to stop it -- the code running on that thread has to cooperate by checking for its interrupted state (using one of those two approaches) and appropriately exiting. For instance, you could replace while(true) with while (!Thread.currentThread().isInterrupted()).

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=77283&siteId=1