Default Exception Handler

We examined the start() method to the extent of saying that “the start() method indirectly calls the run() method,” but let’s examine exactly what happens. The start() method does start another thread of control, but the run() method is not the “main” routine for this new thread. There are other bookkeeping details that must be taken care of first. The thread must be set up in the Java virtual machine before the run() method can execute. This process is shown in Figure 1.1.

Flowchart of the main thread

Figure A-1. Flowchart of the main thread

All uncaught exception conditions are handled by code outside of the run() method before the thread terminates. It is this exception handling that we will examine here.

Why is this exception handler interesting to us? The default exception handler is a Java method; it can be overridden. This means that it is possible for an application to write a new default exception handler. This method looks like this:

void uncaughtException(Thread t, Throwable o)

The default exception handler method, which is called as a final handler to take care of any exceptions not caught by the thread in the run() method. This is a method of the ThreadGroup class.

The default exception handler is a method of the ThreadGroup class. It is called only when an exception is thrown from the run() method. The thread is technically completed when the run() method returns, even though the exception handler is still running in the thread.

But just what is done by the default exception handler? Practically nothing. The only task accomplished by the default exception handler is to print out the stack trace recorded by the Throwable object. This is the stack trace of the thread that threw the object in the first place. (The only exception to this is if the throwable object is a ThreadDeath object, in which case nothing happens. We’ll discuss that situation next.)

Let’s return to the banking example from Chapter 3 . We know that any uncaught exception in our ATM system is unacceptable, so we must handle every exception. But certain problems, like the ATM running out of money, may be encountered in more than one location in our algorithm. Handling the out-of -money condition in the default exception handler may be the best solution.

Let’s examine a possible implementation of our default exception handler:

public class ATMOutOfMoneyException extends RuntimeException {
    public ATMOutOfMoneyException() {
        super();
    }

    public ATMOutOfMoneyException(String s) {
        super(s);
    }
}

public class ATMThreadGroup extends ThreadGroup {
    public ATMThreadGroup(String name) {
        super(name);
    }

    public void uncaughtException(Thread t, Throwable e) {
        if (e instanceof ATMOutOfMoneyException) {
            AlertAdminstrator(e);
        } else {
            super.uncaughtException(t, e);
        }
    }
}

You can implement a default exception handler by overriding the uncaughtException() method. This requires that you subclass the ThreadGroup class, instantiate an instance of that subclass, and create all your threads so that they belong to that instance. The method is passed an instance of the Thread class that threw the object, along with the actual object that was thrown. In our case, we are only concerned with the out-of-money condition. Every other object that is thrown is passed to the original default handler.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset