I discovered this after I spend a whole day trying to find out why did the thread stopped. The cause turned out to be a simple IndexOutOfBondException. If the exception was showed in logcat I would've fixed that in a minute. Can anyone please tell me why throwing a exception in a custom thread causes a thread to stop and how can I catch it and log it?
I used ExecutorService to create and handle my custom thread.
private ExecutorService processingThread = Executors.newSingleThreadExecutor(r -> new Thread(r, "processingThread"));
I use android studio.
Code in the second screenshot is inside the function onDrawFrame() in GLRenderer.
Code in the first screenshot is inside the lambda thingy in the submit function which is in the function onDrawFrame() in GLRenderer(forgive my english).
thanks a lot
You cannot catch exception from Thread directly in your main thread.
When a thread is about to terminate due to an uncaught exception
The Java Virtual Machine will query the thread for its UncaughtExceptionHandler using Thread.getUncaughtExceptionHandler()
and will invoke the handler's uncaughtException method, passing the
thread and the exception as arguments.
If a thread has not had its UncaughtExceptionHandler explicitly set,
then its ThreadGroup object acts as its UncaughtExceptionHandler.
If the ThreadGroup object has no special requirements for dealing with
the exception, it can forward the invocation to the default uncaught
exception handler.
You can catch the runtime exception from thread as follows:
Thread.UncaughtExceptionHandler h = new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread th, Throwable ex) {
Log.e("TEST","Uncaught exception: " + ex);
}
};
final Thread thread = new Thread() {
public void run() {
Log.d("TEST","Performing action...");
throw new RuntimeException("Exception from thread");
}
};
thread.setUncaughtExceptionHandler(h);
thread.start();
Related
Here is my parser class:
public class InputFilesParser {
private ExecutorService executorService;
private volatile Throwable thrownError;
public InputFilesParser(int poolSize) {
this.executorService = Executors.newFixedThreadPool(poolSize, (r) -> {
Thread t = new Thread(r);
t.setUncaughtExceptionHandler((thread, e) -> {
//this should be called before the thread has finished.
this.notifyOnException(thread, e);
});
return t;
});
}
}
public void parseFile(Path inputFilePath) throws Throwable {
//if exception is set, then no more files will be processed.
if (this.thrownError != null) {
//execution will stop here because an error will be thrown from waitToFinish()
this.waitToFinish();
}
this.executorService.execute(() -> {
//this will always throw an exception which have to be handled by the above mentioned uncaughtExceptionHandler.
this.processFile(inputFilePath);
});
}
private void processFile(Path inputFilePath) {
throw new RuntimeExecption();
}
public void waitToFinish() throws Throwable {
this.executorService.shutdown();
while (true) {
try {
//if statement will be entered only when awaitTermination returns true, meaning all the tasks are finished.
if (this.executorService.awaitTermination(STOP_CHECK_TIMEOUT, TimeUnit.SECONDS)) {
synchronized (this) {
//in this scenario, after all tasks are finished, the thrownError should be set
if (this.thrownError != null) {
//I expect to get this output
System.out.println("Exception: " + this.thrownError);
throw this.thrownError;
}
//but I get this output
System.out.println("No exception: " + this.thrownError);
}
break;
}
} catch (InterruptedException e) {
LOG.info("An interruption occurred", e);
}
}
}
private synchronized void notifyOnException(Thread thread, Throwable t) {
//if the thrownError isn't set, then set it here so that waitToFinish() will know that an error occurred.
if (this.thrownError == null) {
this.thrownError = t;
}
}
}
on the calling thread, I have the following:
InputFilesParser ifp = new InputFilesParser(poolSize);
try {
for (Path f : files) {
//each parsing will throw an exception in this scenario
ifp.parseFile(f);
}
//an exception should be detected and the error thrown, but actually this is not happening, but printing No exception... message.
ifp.waitToFinish();
catch(Exception e) {
e.printStackTrace();
}
Although there is an exception thrown, the calling thread gets in waitToFinish() method, printing null for the thrown exception:
Thread: Thread-5. No exception: null
This means that awaitTermination returns true, before the exception is set in notifyOnException method. But notifyOnException method is called from a thread run by this executor service. In my opinion there is a problem with my understanding, or there is a problem with java.
Any idea which one of this :) ? In my opinion, this shouldn't be possible. Am I missing something about setUncaughtExceptionHandler method and the way how it handles the exceptions? Although from documentation it seems that this method is called by the thread throwing the exception.
public void setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)
Set the handler invoked when this thread abruptly terminates due to an uncaught exception.
A thread can take full control of how it responds to uncaught exceptions by having its uncaught exception handler explicitly set. If no such handler is set then the thread's ThreadGroup object acts as its handler.
Parameters:
eh - the object to use as this thread's uncaught exception handler. If null then this thread has no explicit handler.
Thanks in advance.
It seems to me that my assumption in regard to UncaughtExceptionHanlder's method call is wrong.
Java docs says this:
public static interface Thread.UncaughtExceptionHandler
Interface for handlers invoked when a Thread abruptly terminates due to an uncaught exception.
When a thread is about to terminate due to an uncaught exception the Java Virtual Machine will query the thread for its UncaughtExceptionHandler using Thread.getUncaughtExceptionHandler() and will invoke the handler's uncaughtException method, passing the thread and the exception as arguments.
With other words, it is not the thread itself which calls the UncaughtExceptionHandler's method, but JVM. This means that there is no constraint in regard to the order of operations when awaitTermination is called.
In the following scenario my task throws an exception. I was excepting that after one request my pool would not be able to process any further requests but it is not happening. How does thread pool behaves in this scenario? How communication of exception happens from Pool thread to main application thread?
public class CallableClass implements Callable<String> {
#Override
public String call() throws Exception {
throw new RuntimeException();
}
}
class Test {
ExecutorService executor = Executors.newFixedThreadPool(1);
public void execute(){
try {
System.out.println(executor);
Future<String> future = executor.submit(new Task());
System.out.println(executor);
future.get();
}catch(Exception e) {
System.out.println(executor);
e.printStackTrace();
}
}
}
You could check it out by printing the name of the currently executing thread:
#Override
public String call() throws Exception {
System.out.println(Thread.currentThread().getName());
...
}
How does thread pool behaves in this scenario?
The worker notifies the executor service about the exception occurred when it was working. But there is no reason to remove that worker from the ThreadPoolExecutor#workers set. It will continue its work if there is a need.
You shouldn't see any failures of the executor service. It's going to replace an invalid worker (or a thread) with a valid one if something wrong happens:
If any thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.
ExecutorService.newFixedThreadPool(int) [JDK 9]
How communication of exception happens from Pool thread to main application thread?
Any exception thrown from a Callable#call is being wrapped by an ExecutionException and is popped up to the caller:
#throws ExecutionException if the computation threw an exception
Future.get() [JDK 9]
An example of cheching whether ExecutionException#getCause is a RuntimeException instance:
} catch (ExecutionException e) {
Throwable cause = e.getCause();
if (cause != null && cause instanceof RuntimeException) {
System.out.println("A RuntimeException was thrown.");
}
}
I do not understand why the thread does not throw an InterruptedException when interrupted itself.
I'm trying with following snippet:
public class InterruptTest {
public static void main(String[] args) {
MyThread t = new MyThread();
t.start();
try {
t.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
private static class MyThread extends Thread {
#Override
public void run() {
Thread.currentThread().interrupt();
}
} }
In the API docs it says on the interrupt() method:
If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the Thread.join(), Thread.join(long), Thread.join(long, int), Thread.sleep(long), or Thread.sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.
I know this is an old question, but I think the answers above are actually not quite correct. (except #Skylion's, which doesn't really address the question...) :)
Thread.interrupt() does not throw any exceptions by itself. It does two things: First it simply sets an internal interrupted-flag and then it checks if the thread that it was called on is currently blocking on an activity like wait(), sleep(), or join(). If it finds one, then it wakes up that method and causes that method to throw the exception inside the thread it was called on (not from).
In the case where you call interrupt() from the thread itself, that thread obviously can't itself be currently blocking on one of those calls as it is currently executing your interrupt() call. So, only the internal interrupted-flag is set and no exception is thrown at all.
The next time you call one of the blocking methods (like sleep() in #OldCurmudgeon's example) from that thread, that method will notice the interrupted-flag and throw the InterruptedException.
If you don't ever call any of those methods, your thread will simply continue running until it terminates some other way and will never throw an InterruptedException. This is true even if you call interrupt() from a different thread.
So, to notice that your thread has been interrupted, you either need to frequently use one of the blocking methods that throws an InterruptedException and then quit when you receive one of those exceptions, or you need to frequently call Thread.interrupted() to check the internal interrupted-flag yourself and quit if it ever returns true. But you are also free to simply ignore the exception and the result from Thread.interrupted() completely and keep the thread running. So, interrupt() might be a little bit ambiguously named. It doesn't necessarily "interrupt" (as in "terminate") the Thread at all, it simply sends a signal to the thread that the thread can handle or ignore as it pleases. Much like a hardware interrupt signal on a CPU (which is probably where the name comes from).
To have the exception be thrown by the join() method in your main thread, you need to call interrupt() on that thread, rather than on MyThread, like so:
public static void main(String[] args) {
MyThread t = new MyThread();
t.setDaemon(true); // Quit when main thread is done
t.start();
try {
t.join();
} catch (InterruptedException ex) {
System.out.println("Now it works:");
ex.printStackTrace();
}
}
private static class MyThread extends Thread {
private final Thread parentThread;
public MyThread() {
parentThread = Thread.currentThread();
}
#Override
public void run() {
parentThread.interrupt(); // Call on main thread!!!
while (true); // Keep thread running (see comments)
}
}
See #markus-a's answer for what should have been the accepted answer here.
(Mine should be deleted, but I can't do that while it's accepted).
Exceptions are always thrown on their own thread. You have two different threads: your main thread and the one you created. There's no way the exception thrown in MyThread can be caught in the main one.
Why interrupt the thread at all? Just use
return;
You're just being too quick - try this:
private static class MyThread extends Thread {
#Override
public void run() {
try {
Thread.currentThread().interrupt();
Thread.sleep(5000);
} catch (InterruptedException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, "Oops", ex);
}
}
}
I get:
Oct 04, 2013 12:43:46 AM test.Test$MyThread run
SEVERE: Oops
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at test.Test$MyThread.run(Test.java:36)
note that you cannot propagate the exception out of the run method because run does not throw any exceptions.
Exception handling is not designed to process problems associated with asynchronous events (e.g., disk I/O completions, network message arrivals, mouse clicks and keystrokes), which occur in parallel with, and independent of, the program’s flow of control.
How is exception handling not designed to handle asynchronous events? Why is this the case?
I'll be thankful if you enhanced your answers by quite detailed examples.
I think that is a misleading statement.
Asynchronous work is done through threads in Java (or processes but that is a different matter).
What is true is that if you start a thread and an exception is thrown in that thread, you won't be able to catch it from your main thread.
But nothing prevents you from handling exceptions in that new thread.
Example - the code below prints Exception was raised in the thread but we can still handle it:
public static void main(String[] args) throws Exception {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
throw new RuntimeException("oops");
}
});
t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("Exception was raised in the thread but we can still handle it");
}
});
t.start();
}
Alternatively, you can add some exception catching logic within the Runnable itself.
I understand that callable's call can throw the exception to the parent method calling it which is not the case with runnable.
I wonder how because it's a thread method and is the bottommost method of the thread stack.
The point of Callable is to have your exception thrown to your calling thread, for example when you get the result of a Future to which you submitted your callable.
public class CallableClass implements Callable<String> {
...
}
ExecutorService executor = new ScheduledThreadPoolExecutor(5);
Future<Integer> future = executor.submit(callable);
try {
System.out.println(future.get());
} catch (Exception e) {
// do something
}
Callable.call() can't be the bottommost stack frame. It's always called by another method that will then catch the exception. Callable should usually be used to asynchronously compute values and later get them with a Future object. The operation might throw an exception that is later rethrown when you try to get the Future's value.
Runnable is simply supposed to run an operation that doesn't return anything. All exception handling should be done within the Runnable because it's unclear how any exceptions thrown in Runnable.run() should be handled. (The exception from a Callable is usually returned to the caller with the Future)