Future.get() stuck when the runnable throws exception--while running on separate executor service?










3














A repro here:



import java.util.concurrent.*;

public class Main

public static void main(String args) throws ExecutionException, InterruptedException
System.out.println("Hello!");

ExecutorService exec = Executors.newSingleThreadExecutor();

Future<Integer> f = exec.submit(() -> x());

f.get();

System.out.println("f.get() returned");

exec.shutdownNow();

System.out.println("Good bye!");


private static Integer x()
throw new RuntimeException("An unfortunate event");




The output only shows "Hello!" and the exception stacktrace, then gets the program hangs forever.



The changes below kind of work around the problem, but any idea why the execution hangs in the code above?



Using the common thread pool does NOT hang:



Future<Integer> f = ForkJoinPool.commonPool().submit(() -> x());


Wrapping the call around try/catch lets the application exit normally:



Future<Integer> f = exec.submit(() -> x());

try
f.get();
catch (Exception ex)
ex.printStackTrace();










share|improve this question

















  • 4




    Exception thrown from main in get() as expected. This means that execution does not continue past that line. Executor service never shut down so you have a running non-daemon thread. The JVM does not exit. Can you explain what behaviour you expected?
    – Boris the Spider
    Nov 11 at 17:40










  • @BoristheSpider Now that you pointed it out, that's... obvious. I need more sleep/coffee :-) For console applications like this, is there a pragmatic way to safely kill the thread pool so the application can exit besides catching the exception? Maybe try/finally and make sure the thread pool shutdown?
    – Steven Luu
    Nov 11 at 17:44






  • 2




    If you want the JVM to exit even if tasks are still running then just use daemon threads. Otherwise you'll need to faff around with shutdown hooks and the like.
    – Boris the Spider
    Nov 11 at 17:45











  • Alternatively, use a framework like Spring Boot which handles a lot of this stuff for you. But it's a big framework so you need a fairly complex application before it becomes worth it to bring something like that in.
    – Boris the Spider
    Nov 11 at 17:49










  • The CommonPool uses daemon threads by default.
    – Charlie
    Nov 11 at 17:55















3














A repro here:



import java.util.concurrent.*;

public class Main

public static void main(String args) throws ExecutionException, InterruptedException
System.out.println("Hello!");

ExecutorService exec = Executors.newSingleThreadExecutor();

Future<Integer> f = exec.submit(() -> x());

f.get();

System.out.println("f.get() returned");

exec.shutdownNow();

System.out.println("Good bye!");


private static Integer x()
throw new RuntimeException("An unfortunate event");




The output only shows "Hello!" and the exception stacktrace, then gets the program hangs forever.



The changes below kind of work around the problem, but any idea why the execution hangs in the code above?



Using the common thread pool does NOT hang:



Future<Integer> f = ForkJoinPool.commonPool().submit(() -> x());


Wrapping the call around try/catch lets the application exit normally:



Future<Integer> f = exec.submit(() -> x());

try
f.get();
catch (Exception ex)
ex.printStackTrace();










share|improve this question

















  • 4




    Exception thrown from main in get() as expected. This means that execution does not continue past that line. Executor service never shut down so you have a running non-daemon thread. The JVM does not exit. Can you explain what behaviour you expected?
    – Boris the Spider
    Nov 11 at 17:40










  • @BoristheSpider Now that you pointed it out, that's... obvious. I need more sleep/coffee :-) For console applications like this, is there a pragmatic way to safely kill the thread pool so the application can exit besides catching the exception? Maybe try/finally and make sure the thread pool shutdown?
    – Steven Luu
    Nov 11 at 17:44






  • 2




    If you want the JVM to exit even if tasks are still running then just use daemon threads. Otherwise you'll need to faff around with shutdown hooks and the like.
    – Boris the Spider
    Nov 11 at 17:45











  • Alternatively, use a framework like Spring Boot which handles a lot of this stuff for you. But it's a big framework so you need a fairly complex application before it becomes worth it to bring something like that in.
    – Boris the Spider
    Nov 11 at 17:49










  • The CommonPool uses daemon threads by default.
    – Charlie
    Nov 11 at 17:55













3












3








3


1





A repro here:



import java.util.concurrent.*;

public class Main

public static void main(String args) throws ExecutionException, InterruptedException
System.out.println("Hello!");

ExecutorService exec = Executors.newSingleThreadExecutor();

Future<Integer> f = exec.submit(() -> x());

f.get();

System.out.println("f.get() returned");

exec.shutdownNow();

System.out.println("Good bye!");


private static Integer x()
throw new RuntimeException("An unfortunate event");




The output only shows "Hello!" and the exception stacktrace, then gets the program hangs forever.



The changes below kind of work around the problem, but any idea why the execution hangs in the code above?



Using the common thread pool does NOT hang:



Future<Integer> f = ForkJoinPool.commonPool().submit(() -> x());


Wrapping the call around try/catch lets the application exit normally:



Future<Integer> f = exec.submit(() -> x());

try
f.get();
catch (Exception ex)
ex.printStackTrace();










share|improve this question













A repro here:



import java.util.concurrent.*;

public class Main

public static void main(String args) throws ExecutionException, InterruptedException
System.out.println("Hello!");

ExecutorService exec = Executors.newSingleThreadExecutor();

Future<Integer> f = exec.submit(() -> x());

f.get();

System.out.println("f.get() returned");

exec.shutdownNow();

System.out.println("Good bye!");


private static Integer x()
throw new RuntimeException("An unfortunate event");




The output only shows "Hello!" and the exception stacktrace, then gets the program hangs forever.



The changes below kind of work around the problem, but any idea why the execution hangs in the code above?



Using the common thread pool does NOT hang:



Future<Integer> f = ForkJoinPool.commonPool().submit(() -> x());


Wrapping the call around try/catch lets the application exit normally:



Future<Integer> f = exec.submit(() -> x());

try
f.get();
catch (Exception ex)
ex.printStackTrace();







java future executorservice hang executor






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 11 at 17:35









Steven Luu

863513




863513







  • 4




    Exception thrown from main in get() as expected. This means that execution does not continue past that line. Executor service never shut down so you have a running non-daemon thread. The JVM does not exit. Can you explain what behaviour you expected?
    – Boris the Spider
    Nov 11 at 17:40










  • @BoristheSpider Now that you pointed it out, that's... obvious. I need more sleep/coffee :-) For console applications like this, is there a pragmatic way to safely kill the thread pool so the application can exit besides catching the exception? Maybe try/finally and make sure the thread pool shutdown?
    – Steven Luu
    Nov 11 at 17:44






  • 2




    If you want the JVM to exit even if tasks are still running then just use daemon threads. Otherwise you'll need to faff around with shutdown hooks and the like.
    – Boris the Spider
    Nov 11 at 17:45











  • Alternatively, use a framework like Spring Boot which handles a lot of this stuff for you. But it's a big framework so you need a fairly complex application before it becomes worth it to bring something like that in.
    – Boris the Spider
    Nov 11 at 17:49










  • The CommonPool uses daemon threads by default.
    – Charlie
    Nov 11 at 17:55












  • 4




    Exception thrown from main in get() as expected. This means that execution does not continue past that line. Executor service never shut down so you have a running non-daemon thread. The JVM does not exit. Can you explain what behaviour you expected?
    – Boris the Spider
    Nov 11 at 17:40










  • @BoristheSpider Now that you pointed it out, that's... obvious. I need more sleep/coffee :-) For console applications like this, is there a pragmatic way to safely kill the thread pool so the application can exit besides catching the exception? Maybe try/finally and make sure the thread pool shutdown?
    – Steven Luu
    Nov 11 at 17:44






  • 2




    If you want the JVM to exit even if tasks are still running then just use daemon threads. Otherwise you'll need to faff around with shutdown hooks and the like.
    – Boris the Spider
    Nov 11 at 17:45











  • Alternatively, use a framework like Spring Boot which handles a lot of this stuff for you. But it's a big framework so you need a fairly complex application before it becomes worth it to bring something like that in.
    – Boris the Spider
    Nov 11 at 17:49










  • The CommonPool uses daemon threads by default.
    – Charlie
    Nov 11 at 17:55







4




4




Exception thrown from main in get() as expected. This means that execution does not continue past that line. Executor service never shut down so you have a running non-daemon thread. The JVM does not exit. Can you explain what behaviour you expected?
– Boris the Spider
Nov 11 at 17:40




Exception thrown from main in get() as expected. This means that execution does not continue past that line. Executor service never shut down so you have a running non-daemon thread. The JVM does not exit. Can you explain what behaviour you expected?
– Boris the Spider
Nov 11 at 17:40












@BoristheSpider Now that you pointed it out, that's... obvious. I need more sleep/coffee :-) For console applications like this, is there a pragmatic way to safely kill the thread pool so the application can exit besides catching the exception? Maybe try/finally and make sure the thread pool shutdown?
– Steven Luu
Nov 11 at 17:44




@BoristheSpider Now that you pointed it out, that's... obvious. I need more sleep/coffee :-) For console applications like this, is there a pragmatic way to safely kill the thread pool so the application can exit besides catching the exception? Maybe try/finally and make sure the thread pool shutdown?
– Steven Luu
Nov 11 at 17:44




2




2




If you want the JVM to exit even if tasks are still running then just use daemon threads. Otherwise you'll need to faff around with shutdown hooks and the like.
– Boris the Spider
Nov 11 at 17:45





If you want the JVM to exit even if tasks are still running then just use daemon threads. Otherwise you'll need to faff around with shutdown hooks and the like.
– Boris the Spider
Nov 11 at 17:45













Alternatively, use a framework like Spring Boot which handles a lot of this stuff for you. But it's a big framework so you need a fairly complex application before it becomes worth it to bring something like that in.
– Boris the Spider
Nov 11 at 17:49




Alternatively, use a framework like Spring Boot which handles a lot of this stuff for you. But it's a big framework so you need a fairly complex application before it becomes worth it to bring something like that in.
– Boris the Spider
Nov 11 at 17:49












The CommonPool uses daemon threads by default.
– Charlie
Nov 11 at 17:55




The CommonPool uses daemon threads by default.
– Charlie
Nov 11 at 17:55












1 Answer
1






active

oldest

votes


















4














It's always hard to find a good example of try-finally and its appropriate usage. I think it's the case.



try 
f.get();
System.out.println("f.get() returned");
finally
exec.shutdownNow();



The exception thrown from f.get(); wasn't handled, the main thread failed. But the application still contains non-daemon threads manageable by the ExecutorService to which you have no direct access.






share|improve this answer


















  • 2




    Easier in this case - call shutdown after submitting the task before calling get().
    – Boris the Spider
    Nov 11 at 17:48






  • 1




    Thanks! This works. I'm choosing to using daemon threads in my thread pool, since I don't really care for them to exit cleanly.
    – Steven Luu
    Nov 11 at 17:55










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53251394%2ffuturet-get-stuck-when-the-runnable-throws-exception-while-running-on-separ%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









4














It's always hard to find a good example of try-finally and its appropriate usage. I think it's the case.



try 
f.get();
System.out.println("f.get() returned");
finally
exec.shutdownNow();



The exception thrown from f.get(); wasn't handled, the main thread failed. But the application still contains non-daemon threads manageable by the ExecutorService to which you have no direct access.






share|improve this answer


















  • 2




    Easier in this case - call shutdown after submitting the task before calling get().
    – Boris the Spider
    Nov 11 at 17:48






  • 1




    Thanks! This works. I'm choosing to using daemon threads in my thread pool, since I don't really care for them to exit cleanly.
    – Steven Luu
    Nov 11 at 17:55















4














It's always hard to find a good example of try-finally and its appropriate usage. I think it's the case.



try 
f.get();
System.out.println("f.get() returned");
finally
exec.shutdownNow();



The exception thrown from f.get(); wasn't handled, the main thread failed. But the application still contains non-daemon threads manageable by the ExecutorService to which you have no direct access.






share|improve this answer


















  • 2




    Easier in this case - call shutdown after submitting the task before calling get().
    – Boris the Spider
    Nov 11 at 17:48






  • 1




    Thanks! This works. I'm choosing to using daemon threads in my thread pool, since I don't really care for them to exit cleanly.
    – Steven Luu
    Nov 11 at 17:55













4












4








4






It's always hard to find a good example of try-finally and its appropriate usage. I think it's the case.



try 
f.get();
System.out.println("f.get() returned");
finally
exec.shutdownNow();



The exception thrown from f.get(); wasn't handled, the main thread failed. But the application still contains non-daemon threads manageable by the ExecutorService to which you have no direct access.






share|improve this answer














It's always hard to find a good example of try-finally and its appropriate usage. I think it's the case.



try 
f.get();
System.out.println("f.get() returned");
finally
exec.shutdownNow();



The exception thrown from f.get(); wasn't handled, the main thread failed. But the application still contains non-daemon threads manageable by the ExecutorService to which you have no direct access.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 11 at 17:57

























answered Nov 11 at 17:45









Andrew Tobilko

25.8k104284




25.8k104284







  • 2




    Easier in this case - call shutdown after submitting the task before calling get().
    – Boris the Spider
    Nov 11 at 17:48






  • 1




    Thanks! This works. I'm choosing to using daemon threads in my thread pool, since I don't really care for them to exit cleanly.
    – Steven Luu
    Nov 11 at 17:55












  • 2




    Easier in this case - call shutdown after submitting the task before calling get().
    – Boris the Spider
    Nov 11 at 17:48






  • 1




    Thanks! This works. I'm choosing to using daemon threads in my thread pool, since I don't really care for them to exit cleanly.
    – Steven Luu
    Nov 11 at 17:55







2




2




Easier in this case - call shutdown after submitting the task before calling get().
– Boris the Spider
Nov 11 at 17:48




Easier in this case - call shutdown after submitting the task before calling get().
– Boris the Spider
Nov 11 at 17:48




1




1




Thanks! This works. I'm choosing to using daemon threads in my thread pool, since I don't really care for them to exit cleanly.
– Steven Luu
Nov 11 at 17:55




Thanks! This works. I'm choosing to using daemon threads in my thread pool, since I don't really care for them to exit cleanly.
– Steven Luu
Nov 11 at 17:55

















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53251394%2ffuturet-get-stuck-when-the-runnable-throws-exception-while-running-on-separ%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Use pre created SQLite database for Android project in kotlin

Darth Vader #20

Ondo