starting a new thread in existing thread's uncaughtexception handler - java

If an uncaught exception is thrown and you want to recover by restarting an identical thread to the one the exception was just thrown in (e.g JMS connection lost), what's the easiest way?
The class extends from Thread, and the thread has an UncaughtExceptionHandler.

The easiest thing to do is to "restart" the current thread via the run() method
void run() {
boolean done = false;
while(!done) {
try {
...
done = true;
} catch (ConnectionLostException ex) {
// log exception
}
}
}

Related

How to reset interrupted flag in executorservice.invokeAll()

I've learnt that it is the good practice to set Thread.interrupter() flag back to true after catching a InterruptedException.
However when I call executorService.invokeAll() and put a try clause around it, by catching the InterruptedException, will Thread.currentThread().interrupt() correctly flag the interrupted thread, or the main thread of my controller/runner?
public class Controller {
public void run() {
final List<Task> tasks = request.collectTasks()
try {
executorService.invokeAll(tasks);
} catch (InterruptedException e) {
message = "interrupted";
Thread.currentThread().interrupt();
throw new InternalFailureException(message);
}
}
}
class Task implements Callable<String> {
#Override
public String call() {
return taskId;
}
}
Overall is this the correct way to reset the interrupted flag?
In this code example you have given
try {
executorService.invokeAll(tasks);
} catch (InterruptedException e) {
message = "interrupted";
Thread.currentThread().interrupt();
throw new InternalFailureException(message);
}
whoever invokes Thread.currentThread().interrupt(); will set the flag of that thread in this example it will be the thread executing your Controller#run() method.
Ideally with executors it is the responsibility of Task or Runnable which gets scheduled over the executor to handle this flag properly.
Since it is a checked exception already - it will not give you an opportunity to decorate the task that you are about to submit inside executor so you have no easy control over it.

Stopping a Thread / Threads calls interrupt on itself after crash?

I am currently running a Thread from a Service to do some background work.
Now there is the possibility that the Thread crashes or I want to
interrupt the thread from the Service. So how am I supposed to:
stop the Thread realiable, (hard)
catch exceptions and call the Service about the crash
handle InterruptedException if interrupted while sleep()
is Thread.isInterrupted a good way to detect if the Thread stopped?
What I have done so far is the following:
#Override
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
doMyBackgroundWork();
sleep();
}
}catch(Exception e){
ExceptionHandler.logAndSendException(e);
Thread.currentThread().interrupt();
if(crashedListener != null){
crashedListener.onThreadCrashed();
}
}
LOG.i("Thread stops now.");
}
private void sleep() {
try {
sleep(frequency);
} catch (InterruptedException e) {
//what to do here? it can happen because I stopped it myself
}
}
So at first I am running my Thread until it gets interrupted.
If any exception occurs, I want to start a new Thread, therefore
my Service implements a listener interface and I call it, once an
Exception is thrown. I know that catching everything is discouraged,
but I need to know if the Thread stops, without polling Thread.isAlive()
all the time.
Additionally to my four questions above:
is my code reliable and does what I need?
is it ok to call interrupt on the Thread itself?
Thanks!
You are not actually interrupting your own thread because the catch block is outside of the while loop. Therefore, any exception would stop execution immediately.
Interruption is essentially just a request (usually from another thread) to stop doing what you are doing. The thread is free to ignore it and keep doing what it is doing. Normally you have to throw an exception in response to an interrupt, or stop execution some other way such as just breaking from the loop (you need this around the //what to do here? comment). It so happens that some library methods are "responsive to interruption" meaning they will throw an exception if the thread is ever interrupted, such as Thread.sleep(), which you will most likely have in your sleep call.
I recommend picking Java Concurrency In Practice. Among the excellent concurrency material, there is a chapter on interrupts which is very helpful.
EDIT:
I would remove the code where you interrupt your own thread. You will also need to rethrow the InterruptedException as a runtime exception to get out of the execution loop. Usually people will create a new Exception that extends RuntimeException that is something like MyInterruptedException. You can then add it to the catch block around your loop so that you know when the thread was interrupted vs execution failed.
As a general example you can do something like this:
public void run() {
try {
while (true) {
// check for interrupts in the loop, or somewhere in the work method
if (Thread.interrupted()) {
throw new MyInterruptedException("Important thread interrupted.");
}
doMyBackgroundWork();
sleep();
}
}
catch(Exception e){
ExceptionHandler.logAndSendException(e);
if(crashedListener != null){
crashedListener.onThreadCrashed();
}
}
catch(MyInterruptedException i) {
LOG.i("Execution stopping because of interrupt.");
}
}
private void sleep() {
try {
sleep(frequency);
} catch (InterruptedException e) {
throw new MyInterrptedException(e);
}
}
we have a nice and effective method called stop()(Thread.stop(void):void) which is deprecated, but it works and it's lovely.
Note that stop() throws ThreadDeath at the target thread which is not an exception(and it could any other throwable too), but an Error, so your code will not catch any signal about this.
public void run() {
try {
while (<<using_a_volatile_bool_type_is_better>>) {
...
}
}catch(Throwable t){/**/}/*use throwable instead of exception.*/}
}
Beside dear friend stop() we also have pause() method too, and it really pauses the target thread.
Not just one solution out there, but if it's really critical to keep thread run and run the emergency(or itself) just after any crash, you may run it as a separately app/process, plus get progress status(if any) that ensures you the target thread/app is not freezed(blocked,...)

Sleep inner thread without sleeping outer thread - Java

I have a main Mina handler thread is processing and in that thread i made another thread and set it to sleep for specified time. Now i want that this inner thread sleep independently without blocking Handler thread.
following is sample code.
public void messageReceived(IoSession session, Object message) throws Exception {
Integer tts = 5000;
Thread sleepThread = new Thread(obj);
sleepThread.sleep(tts);
}
currently it is blocking main Handler thread.
Thread.sleep() is a static method, so calling sleepThread.sleep(tts) is the same as Thread.sleep(tts). Hence your current thread is just sleeping.
You can't cause another thread to sleep by calling a method on its Thread object. At a push, you could set a flag on the object and your thread could check for the presence of that flag and behave accordingly.
try
final int tts = 5000;
Thread sleepThread = new Thread() {
public void run() {
try {
Thread.sleep(tts);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
};
sleepThread.start();

Catching exceptions from another threads?

I am writing an app that will make use of multiple threads. There is main thread that is launching another threads. What i want to acomplish is when one of the launched threads throws an exception, the main thread should stop launching threads. It looks more or less like this:
class SomeClass {
boolean launchNewThread = true;
public static void main() {
while (launchNewThread) {
try {
AnotherClass.run();
} catch (CrossThreadException e) {
launchNewThread = false;
}
}
}
}
class AnotherClass implements Runnable {
public void run() {
if (a=0) throw new CrossThreadException();
}
}
You should do it yourself - catch the exception and pass it somehow into the launching thread.
Also, there is Future concept, which does it already. You should launch your threads as futures and check isDone(), and catch ExecutionException from get(), this exception will be thrown if a future's task thrown an exception.
You can also use a listener as described in How to throw a checked exception from a java thread?
When an exception is thrown inside one of the child threads, you could call a method like listener.setLaunchNewThread(false) from the child thread which will change the value of your boolean flag in the parent thread.
On a side note, calling AnotherClass.run() does not start a new thread but only call the run method from AnotherClass within the same thread. Use new Thread(new AnotherClass()).start() instead.

How to throw a checked exception from a java thread?

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 is, that the compiler doesn't let me to put any code throwing (checked) exceptions into run(). It says:
run() in (...).Listener cannot implement run() in java.lang.Runnable; overridden method does not throw java.io.IOException
I want the exception to kill the thread, and let it be caught somewhere in the parent thread. Is this possible to achieve or do I have to handle every exception inside the thread?
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).
Caveat: this may not meet your needs if you have to use the exception mechanism.
If I understand you correctly, you don't actually need the exception to be checked (you've accepted the answer suggesting an unchecked exception) so would a simple listener pattern be more appropriate?
The listener could live in the parent thread, and when you've caught the checked exception in the child thread, you could simply notify the listener.
This means that you have a way of exposing that this will happen (through public methods), and will be able to pass more information than an exception will allow. But it does mean there will be a coupling (albeit a loose one) between the parent and the child thread. It would depend in your specific situation whether this would have a benefit over wrapping the checked exception with an unchecked one.
Here's a simple example (some code borrowed from another answer):
public class ThingRunnable implements Runnable {
private SomeListenerType listener;
// assign listener somewhere
public void run() {
try {
while(iHaveMorePackets()) {
doStuffWithPacket();
}
} catch(Exception e) {
listener.notifyThatDarnedExceptionHappened(...);
}
}
}
The coupling comes from an object in the parent thread having to be of type SomeListenerType.
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();
}
}
}
What I do is to catch the exception in the thread and store it as a member variable of the Runnable. This exception is then exposed via a getter on the Runnable. I then scan all the threads from the parent to see if any had exceptions, and take the appropriate action.
If you really cannot do anything useful when the exception is raised you can wrap the checked exception in a RuntimeException.
try {
// stuff
} catch (CheckedException yourCheckedException) {
throw new RuntimeException("Something to explain what is happening", yourCheckedException);
}
the thread can't throw the exception to any other thread (nor to the main thread). and you cannot make the inherited run() method throw any checked exceptions since you can only throw less than the inherited code, not more.
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
On the assumption that your code is in some kind of loop, you'd write:
public class ThingRunnable implements Runnable {
public void run() {
try {
while(iHaveMorePackets()) {
doStuffWithPacket()
}
} catch(Exception e) {
System.out.println("Runnable terminating with exception" + e );
}
}
}
The exception will automatically break you out of your loop, and at the end of the run() method, the thread will stop.
Use this Runnable to create your Thread:
public abstract class TryRunner implements Runnable{
protected abstract void tryToRun();
protected void onException(Exception e){}
#Override
final public void run() {
try{ tryToRun(); }catch(Exception e){ e.printStackTrace(); onException(e); }
}
}
Wrapping your exception inside a RuntimeException seems to do the trick.
someMethod() throws IOException
{
try
{
new Thread(() ->
{
try
{
throw new IOException("a checked exception thrown from within a running thread");
}
catch(IOException ex)
{
throw new RuntimeException("a wrapper exception", ex); // wrap the checked exception inside an unchecked exception and throw it
}
}).start();
}
catch(RuntimeException ex) // catch the wrapped exception sent from within the thread
{
if(ex.getCause() instanceof IOException)
throw ex.getCause; // unwrap the checked exception using getCause method and use it however you need
else
throw ex;
}
}

Categories