Sunday, March 18, 2007

Exceptions and Threads

Exception handling is a method of trapping or coping with anticipated errors (system, data entry or calculation) and handling or dealing with them in a graceful manner. The Exception class of objects offers a rich group of subclasses to trap specific errors and recover from them.

A thread is the flow of execution of a single set of program statements. Multithreading consists of multiple sets of statements which can be run in parallel. With a single processor only one thread can run at a time but strategies are used to make it appear as if the threads are running simultaneously. Depending on the operating system, either timeslicing or interrupt methods will move the processing from one thread to the next.

What Exceptions Are

Exceptions are objects that describe any error caused by an external resource not being available or an internal processing problem. They are passed to exception handlers written by the programmer to enable graceful recovery. If the handler has not been written, the program will terminate with a display of the Exception class. There are many exception classes such as IOException and NumberFormatException.

Exception Handling

Java uses the try - catch - finally syntax to test (ie. try) a section of code and if an error occurs in that region, to trap (ie. catch) the error. Any number of catches can be set up for various exception types. The finally keyword can be used to provide a block of code that is performed regardless of whether an exception is signaled or not. The syntax is:

try

{

// tested statement(s);

}

catch (ExceptionName e1)

{

// trap handler statement(s);

}

catch (ExceptionName e2) // any number of catch statements

{

// display exception to screen

System.out.println("Exception: " + e2);

}

finally

{

// always executed block

}

throws and throw Keywords

throws is used to pass a possible exception up the stack (processing chain). The Java compiler is aware of how some methods may cause specific exceptions and it forces you to deal with these immediately. N.B.: If you choose not to write an exception handler then use the throws xxxException clause on the surrounding method to abdicate responsibility. For example using System.input() will give a compile error for IOException. Add the throws clause to the method to pass the error to next level (or else write your own catch/try handler).

The throw keyword (note the singular form) is used to force an exception. It can also pass a custom message to your exception handling module. For example:

throw new FileNotFoundException("Could not find beatles.txt");

Effective Hierarchy

The exception classes are arranged in a hierarchy. Handlers (or catches) for specific exceptions should always be written prior to the generic handler. For example since FileNotFoundException is a child of IOException, a catch for FileNotFoundException should occur before the one for IOException. The latter handler will catch those exceptions that are missed by individual child handlers. And a generic handler for Exception would cover any missing situation.

FileInputStream fis=null;  // declare in outer block

try

{

fis = new FileInputStream (new File (args[0])); // uses cmd line

int ch;

while (ch = fis.read() != -1)

{System.out.print ((char) ch);}

fis.close();

System.out.println("");

}

catch (FileNotFoundException e)

{

System.out.println("File not found!");

try

{

fis.close();

}

catch (IOException ioe) {} // disregard close failure

}

catch (IOException e)

{

try

{

fis.close();

}

catch (IOException ioe) {} // disregard close failure

System.out.println("Unable to read file!");

}

Assertions

Many modern programming languages let you test assumptions with an assertion construct. Java uses assert to test the validity of a logic statement such as assert a. If the assertion is not true, an AssertionError exception is thrown. assert a will attach a custom error message to the exception for display purposes. Common uses are to check for null strings passed in as method parameters and to prevent the possibilitiy of division by zero.

NOTE: To enable asssertion testing at runtime you must use a -ea switch on the command line. If using an IDE you must RTFM.

Reflection

Reflection is the capability for one object to inspect another object's characteristics. It uses classes provided by the java.lang.reflect package. These classes are Field, Method, Constructor, Array and Modifier.

A useful example of reflection is provided by SeeMethods.java (found in http://home.cogeco.ca/~ve3ll/bin2/jp7collections.zip). Compile with javac SeeMethods.java and then run it with java SeeMethods classname This will give a display of all methods in classname as well as their modifiers, return type and parameters.


Using The Thread Class

The Thread Class allows multitasking (ie running several tasks at the same time) by instantiating (ie creating) many threaded objects, each with their own run time characteristics. One way is to extend the Thread class and override the run() method such as:

class HelloThread extends Thread

{

public void run()

{

for int x=0;x<100; style=""> System.out.print(" Hello ");

}

}

However if you need to inherit from another class as well, you can implement a Runnable interface instead.

class HelloThread implements Runnable

{

Thread t = new Thread(this);

t.start();

public void run()

{

for int x=0;x<100; style=""> System.out.print(" Hello ");

}

}

Thread object methods are used on instantiated thread objects to control the thread appropriately. These methods include run(), start(), sleep(longInt), join(), isAlive(), currentThread(), getName(), setName(string), getPriority() and setPriority(int).

Some older methods such as stop(), suspend() and resume() have been deprecated as they sometimes caused system instability or hangup! A better way of stopping a thread is making the run method into a while loop based on a logical that can be set to false as in:

public void run() {

while (okToRun==true) {

// do the run time stuff here

}

}

Inner classes are used to set up multiple threads in a utility.

Assigning Priority

Priority is ranking. Some threads can either run for a longer timeslice or run more often (depending on the operating system). Peers (or equals) get the same time/number of runs. Priority is set from MIN_PRIORITY (currently 1) to MAX_PRIORITY (currently 10) using the setPriority(int) method. NORM_PRIORITY is the midrange value (currently 5). These constants are defined in the Thread class.

Example: Digital Clock

A good example of using threads for animation is the applet .Clock.zip. A ready-to-run version is found in http://home.cogeco.ca/~ve3ll/bin2/jp7collections.zip. The output could also be displayed in the browser's status line by using the showStatus(string_msg) method.

/**

* The Clock class demonstrates animation with threads

*/

import java.awt.*; import java.applet.*; import java.util.*;



public class clock extends Applet implements Runnable

{

Font f = new Font("TimesRoman",Font.BOLD,24);

Date d; Thread runner;



public void init()

{resize(300,100);}



public void paint(Graphics g)

{g.setFont(f);g.drawString(d.toString(),10,50);}



public void start()

{

while (runner == null)

{

runner = new Thread(this); runner.start();

}

}



public void run()

{

while (true)

{

d = new Date(); repaint();

try {Thread.sleep(1000);}

catch(InterruptedException e){};

}

}

}

Example: Splash Screen

Splash screens are opening screens that many commercial programs use to 'spiff' up their appearance. Once a splash has run for a set time or when user interrupted it is tossed away and the actual application appears. Program ending credits can be rolled in the same way but done at application close time instead.

ExtendThreadClass.java (found in http://home.cogeco.ca/~ve3ll/bin2/jp7collections.zip) is an extended java class that can be easily adapted into a splash screen. SimpleThread.java (found in http://home.cogeco.ca/~ve3ll/bin2/jp7collections.zip is an implemented class that also illustrates how a user interrupt can force a fast finish to the splash.

Example: Animation

Animation is the appearance of life or movement in an object. It is achieved by redrawing screens with objects shifted slightly. Realistic movement is achieved by appropriate choices of shift and refresh rate.

AniMain.java (found in http://home.cogeco.ca/~ve3ll/bin2/jp7collections.zip) is a simple Java game that involves animation. Read the source code for techniques on using threads to make objects appear to have life by rapid screen redraws.

No comments: