Future.get() stuck when the runnable throws exception--while running on separate executor service?
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
add a comment |
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
4
Exception thrown from main inget()
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
add a comment |
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
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
java future executorservice hang executor
asked Nov 11 at 17:35
Steven Luu
863513
863513
4
Exception thrown from main inget()
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
add a comment |
4
Exception thrown from main inget()
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
add a comment |
1 Answer
1
active
oldest
votes
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.
2
Easier in this case - callshutdown
after submitting the task before callingget()
.
– 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
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
2
Easier in this case - callshutdown
after submitting the task before callingget()
.
– 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
add a comment |
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.
2
Easier in this case - callshutdown
after submitting the task before callingget()
.
– 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
add a comment |
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.
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.
edited Nov 11 at 17:57
answered Nov 11 at 17:45
Andrew Tobilko
25.8k104284
25.8k104284
2
Easier in this case - callshutdown
after submitting the task before callingget()
.
– 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
add a comment |
2
Easier in this case - callshutdown
after submitting the task before callingget()
.
– 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
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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