0

I've got simple test code:

public static void main(String[] args) {
    CompletionService<Integer> cs = new ExecutorCompletionService<>(Executors.newCachedThreadPool());
    cs.submit(new Callable<Integer>() {
        public Integer call(){
            try{
                Thread.sleep(3000); // Just sleep and print
                System.out.println("Sleeping thread: " + Thread.currentThread().getId());
            }catch(InterruptedException e){
                e.printStackTrace();
            }
            return 10;
        }
    });
    try{
        Future<Integer> fi = cs.take();
        System.out.println(fi.get());
    }catch(Exception e){
        e.printStackTrace();
    }
}

I run it, sleep 3 seconds, and prints

Sleeping thread: 14
10

But then it hangs there, the program doesn't end.

What's happening, how to make it finish?

1
  • 2
    The thread in your executor is a user thread, not a daemon thread, so the JVM won't exit until it times out (60 seconds by default)
    – tgdavies
    Commented Jun 18, 2022 at 7:10

1 Answer 1

2

As mentioned in the comments by tgdavies, your program will exit after +/- 60 seconds, because that is the default timeout for a thread without tasks in an ExecutorService created by Executors.newCachedThreadPool().

If you don't want to wait for 60 seconds, you should shutdown the executor service after you're done submitting tasks.

For example:

public static void main(String[] args) {
    ExecutorService executorService = Executors.newCachedThreadPool();
    try {
        CompletionService<Integer> cs = new ExecutorCompletionService<>(executorService);
        cs.submit(new Callable<Integer>() {
            public Integer call() {
                try {
                    Thread.sleep(3000); // Just sleep and print
                    System.out.println("Sleeping thread: " + Thread.currentThread().getId());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return 10;
            }
        });
        try {
            Future<Integer> fi = cs.take();
            System.out.println(fi.get());
        } catch (Exception e) {
            e.printStackTrace();
        }
    } finally {
        executorService.shutdown();
    }
}

Alternatively, configure the executor service to create daemon threads using a custom ThreadFactory. Only do this if it is not a problem that an executor service that is doing actual work gets "killed" when there are no more normal (non-daemon) threads.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.