Hey, I\'m writing a network application, in which I read packets of some custom binary format. And I\'m starting a background thread to wait for incoming data. The problem i
This answer is based on Esko Luontola one but it provides a working example.
Unlike the run() method of the Runnable interface the call() method of Callable allows to throw some exceptions. Here is an implementation example :
public class MyTask implements Callable<Integer> {
private int numerator;
private int denominator;
public MyTask(int n, int d) {
this.numerator = n;
this.denominator = d;
}
@Override
// The call method may throw an exception
public Integer call() throws Exception {
Thread.sleep(1000);
if (denominator == 0) {
throw new Exception("cannot devide by zero");
} else {
return numerator / denominator;
}
}
}
Executor provides a mechanism to run a Callable inside a thread and to handle any kind of exceptions :
public class Main {
public static void main(String[] args) {
// Build a task and an executor
MyTask task = new MyTask(2, 0);
ExecutorService threadExecutor = Executors.newSingleThreadExecutor();
try {
// Start task on another thread
Future<Integer> futureResult = threadExecutor.submit(task);
// While task is running you can do asynchronous operations
System.out.println("Something that doesn't need the tasks result");
// Now wait until the result is available
int result = futureResult.get();
System.out.println("The result is " + result);
} catch (ExecutionException e) {
// Handle the exception thrown by the child thread
if (e.getMessage().contains("cannot devide by zero"))
System.out.println("error in child thread caused by zero division");
} catch (InterruptedException e) {
// This exception is thrown if the child thread is interrupted.
e.printStackTrace();
}
}
}
To be able to send the exception to the parent thread, you can put your background thread in a Callable (it allows throwing also checked exceptions) which you then pass to the submit method of some Executor. The submit method will return a Future which you can then use to get the exception (its get method will throw an ExecutionException which contains the original exception).
If your thread's code throw a RuntimeExpection, you doesn't need to add run() throw Exception.
But use this solution only when appropriate because this can be a bad pratice: http://java.sun.com/docs/books/tutorial/essential/exceptions/runtime.html
Any RuntimeException or unchecked Exception can help you. Maybe you'll need to create your own RuntimeException