0% found this document useful (0 votes)
0 views

Module 4

The document provides an overview of Java exception handling and threading concepts. It explains how exceptions are created, caught, and handled using keywords like try, catch, throw, and finally, as well as the structure of exception types. Additionally, it covers thread creation, management, synchronization, and inter-thread communication, highlighting the importance of thread priorities and the use of the Runnable interface.

Uploaded by

Vinay Adari
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
0 views

Module 4

The document provides an overview of Java exception handling and threading concepts. It explains how exceptions are created, caught, and handled using keywords like try, catch, throw, and finally, as well as the structure of exception types. Additionally, it covers thread creation, management, synchronization, and inter-thread communication, highlighting the importance of thread priorities and the use of the Runnable interface.

Uploaded by

Vinay Adari
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 42

MODULE 4

Exception Handling
A Java exception is an object that describes an exceptional (that is, error) condition that has occurred in a
piece of code. When an exceptional condition arises, an object representing that exception is created and
thrown in the method that caused the error. That method may choose to handle the exception itself, or pass it
on. Either way, at some point, the exception is caught and processed. Exceptions can be generated by the Java
run-time system, or they can be manually generated by code.
Java exception handling is managed via five keywords: try, catch, throw, throws, and finally.
Program statements that want to monitor for exceptions are contained within a try block. If an exception
occurs within the try block, it is thrown. Then code can catch this exception (using catch) and handle it in
some rational manner.
To manually throw an exception, use the keyword throw. Any exception that is thrown out of a method must
be specified as such by a throws clause. Any code that absolutely must be executed after a try block completes
is put in a finally block.
This is the general form of an exception-handling block:
Exception Types:
All exception types are subclasses of the built-in class Throwable. Thus, Throwable is at the top of the
exception class hierarchy. Immediately below Throwable are two subclasses that partition exceptions into two
distinct branches. One branch is headed by Exception. This class is used for exceptional conditions that user
programs should catch.
There is an important subclass of Exception, called RuntimeException. Exceptions of this type are
automatically defined for the programs that is written and include things such as division by zero and invalid
array indexing.
Exceptions of type Error are typically created in response to catastrophic failures that cannot usually be
handled by program.
Uncaught Exceptions:
This small program includes an expression that intentionally causes a divide-by-zero error:

When the Java run-time system detects the attempt to divide by zero, it constructs a new exception object and
then throws this exception. This causes the execution of Exc0 to stop, because once an exception has been
thrown, it must be caught by an exception handler and dealt with immediately.

The stack trace will always show the sequence of method invocations that led up to the error. For example,
here is another version of the preceding program that introduces the same error but in a method separate from
main( ):

Using try and catch:


To handle a run-time error, simply enclose the code to monitor inside a try block. Immediately following the
try block, include a catch clause that specifies the exception type catch. To illustrate how easily this can be
done, the following program includes a try block and a catch clause that processes the ArithmeticException
generated by the division-by-zero error:Notice that the call to println( ) inside the try block is never executed.

Once an exception is thrown, program control transfers out of the try block into the catch block. Put
differently, catch is not “called,” so execution never “returns” to the try block from a catch. Thus, the line
"This will not be printed." is not displayed. Once the catch statement has executed, program control continues
with the next line in the program following the entire try / catch mechanism.
A try and its catch statement form a unit. The scope of the catch clause is restricted to those statements
specified by the immediately preceding try statement. A catch statement cannot catch an exception thrown by
another try statement (except in the case of nested try statements)
Multiple catch Clauses:
In some cases, more than one exception could be raised by a single piece of code. To handle this type of
situation,specify two or more catch clauses, each catching a different type of exception.

This program will cause a division-by-zero exception if it is started with no command-line arguments, since
a will equal zero. It will survive the division if you provide a command-line argument, setting a to something
larger than zero. But it will cause an ArrayIndexOutOfBoundsException, since the int array c has a length of
1, yet the program attempts to assign a value to c[42].

When multiple catch statements is used, it is important to remember that exception subclasses must come
before any of their superclasses. This is because a catch statement that uses a superclass will catch exceptions
of that type plus any of its subclasses. Thus, a subclass would never be reached if it came after its superclass.
Since ArithmeticException is a subclass of Exception, the first catch statement will handle all Exception-
based errors, including ArithmeticException. This means that the second catch statement will never execute.
To fix the problem, reverse the order of the catch statements.

Nested try Statements:


The try statement can be nested. That is, a try statement can be inside the block of another try. Each time a
try statement is entered, the context of that exception is pushed on the stack. If an inner try statement does not
have a catch handler for a particular exception, the stack is unwound and the next try statement’s catch
handlers are inspected for a match.
The output of the program is:

Here is the previous program recoded so that the nested try block is moved inside the method nesttry( ):
The output of this program is identical to that of the preceding example.

throw:
It is possible for a program to throw an exception explicitly, using the throw statement. The general form of
throw is shown here:
throw ThrowableInstance;
Here, ThrowableInstance must be an object of type Throwable or a subclass of Throwable.
There are two ways to obtain a Throwable object: using a parameter in a catch clause or creating one
with the new operator.

Here is a sample program that creates and throws an exception. The handler that catches the exception
rethrows it to the outer handler.
throws:
If a method is capable of causing an exception that it does not handle, it must specify this behavior so that
callers of the method can guard themselves against that exception. To do this by including a throws clause in
the method’s declaration. A throws clause lists the types of exceptions that a method might throw.
Here, exception-list is a comma-separated list of the exceptions that a method can throw.

Following is an example of an incorrect program that tries to throw an exception that it does not catch. Because
the program does not specify a throws clause to declare this fact, the program will not compile.
To make this example compile, need to make two changes. First, to declare that throwOne( ) throws
IllegalAccessException. Second, main( ) must define a try / catch statement that catches this exception. The
corrected example is shown here:
finally:
finally creates a block of code that will be executed after a try /catch block has completed and before the code
following the try/catch block. The finally block will execute whether or not an exception is thrown. If an
exception is thrown, the finally block will execute even if no catch statement matches the exception.

Here is an example program that shows three methods that exit in various ways, none without executing their
finally clauses:
Java’s Built-in Exceptions:
Inside the standard package java.lang, Java defines several exception classes. A few have been used by the
preceding examples. The most general of these exceptions are subclasses of the standard type
RuntimeException.
In the language of Java, these are called unchecked exceptions because the compiler does not check to see if
a method handles or throws these exceptions.
Java’s Unchecked RuntimeException Subclasses Defined in java.lang:
Java’s Checked Exceptions Defined in java.lang:
Exceptions defined by java.lang that must be included in a method’s throws list if that method can generate
one of these exceptions and does not handle it itself. These are called checked exceptions.

THREADS
Thread(Flow of Execution):
• Multitasking(Executing several task simultaneously)
• Process Based(Each task is separate independent process eg.OS-level)
• Thread Based(Each task is the part of the same program
eg.Programmatic level)
• Two ways to define a thread
• By extending Thread class
• By implementing Runnable Interface

The java Thread Model:

(i) Thread Priorities


(ii)Synchronization
(iii) Messaging
(iv) The Thread Class and the Runnable Interface (i)Thread
Priorities :
The rules that determine when a context switch takes place are simple:
• A thread can voluntarily relinquish control. This occurs when explicitly yielding, sleeping, or when
blocked. In this scenario, all other threads are examined, and the highest- priority thread that is ready to run
is given the CPU.
• A thread can be preempted by a higher-priority thread. In this case, a lower priority thread that does not
yield the processor is simply preempted—no matter what it is doing—by a higher-priority thread. Basically,
as soon as a higher-priority thread wants to run, it does. This is called preemptive multitasking.
• Range of Thread priority 1-10
• Access specifier is public static final
• MAX_PRIORITY=10
• NORM_PRIORITY=5
• MIN_PRIORITY=1
(ii) Synchronization(several threads are trying to access the same object simultaneously):
Java implements an elegant twist on an age old model of inter process synchronization: the monitor. The
monitor is a control mechanism first defined by C.A.R. Hoare. Once a thread enters a monitor, all other threads
must wait until that thread exits the monitor. In this way, a monitor can be used to protect a shared asset from
being manipulated by more than one thread at a time. In Java, there is no class “Monitor”; instead, each object
has its own implicit monitor that is automatically entered when one of the object’s synchronized methods is
called. Once a thread is inside a synchronized method, no other thread can call any other synchronized method
on the same object.
(iii) Messaging:
Java provides a clean, low-cost way for two or more threads to talk to each other, via calls to predefined
methods that all objects have. Java’s messaging system allows a thread to enter a synchronized method on an
object, and then wait there until some other thread explicitly notifies it to come out.
(iv) The Thread Class and the Runnable Interface
• Thread encapsulates a thread of execution
• To create a new thread, your program will either extend Thread or implement the Runnable interface.
The Thread class defines several methods that help manage threads.
The main Thread:
The main thread is important for two reasons:
• It is the thread from which other “child” threads will be spawned.
• Often, it must be the last thread to finish execution because it performs various shutdown actions.
static Thread currentThread( )
This method returns a reference to the thread in which it is called It is a public
static member of Thread.

Output:
• By default, the name of the main thread is main. Its priority is 5, which is the default value, and main
is also the name of the group of threads to which this thread belongs. A thread group is a data structure
that controls the state of a collection of threads as a whole.
• The sleep( ) method causes the thread from which it is called to suspend execution for the specified
period of milliseconds. Its general form is shown here:
static void sleep(long milliseconds) throws InterruptedException
The number of milliseconds to suspend is specified in milliseconds. This method may throw an
InterruptedException.
The sleep( ) method has a second form, shown next, which allows you to specify the period in terms of
milliseconds and nanoseconds:
static void sleep(long milliseconds, int nanoseconds) throws InterruptedException
This second form is useful only in environments that allow timing periods as short as nanoseconds.
• set the name of a thread by using setName( )
• can obtain the name of a thread by calling getName( )
final void setName(String threadName) final String
getName( )
Here, threadName specifies the name of the thread.

Creating a Thread:
Create a thread by instantiating an object of type Thread. Java defines two
ways in which this can be accomplished:
• By implement the Runnable interface.
• By can extend the Thread class, itself. Implementing
Runnable:
The easiest way to create a thread is to create a class that implements the Runnable interface. Runnable
abstracts a unit of executable code. To implement Runnable, a class need only implement a single method
called run( ), which is declared like this:
public void run( )
After create a class that implements Runnable, instantiate an object of type Thread from within that class.
Thread defines several constructors.
Thread(Runnable threadOb, String threadName)
In this constructor, threadOb is an instance of a class that implements the Runnable interface. This defines
where execution of the thread will begin. The name of the new thread is specified by threadName.
After the new thread is created, it will not start running until you call its start( ) method, which is declared
within Thread. In essence, start( ) initiates a call to run( ). The start( ) method is shown here:
void start( )
Output:

Extending Thread:
The second way to create a thread is to create a new class that extends Thread, and then to create an
instance of that class. The extending class must override the run( ) method, which is
the entry point for the new thread. As before, a call to start( ) begins execution of the new thread.
This program generates the same output as the preceding version. As the child thread is created by
instantiating an object of NewThread, which is derived from Thread.
Notice the call to super( ) inside NewThread. This invokes the following form of the Thread constructor:
public Thread(String threadName)
Here, threadName specifies the name of the thread. Choosing an
Approach:
The Thread class defines several methods that can be overridden by a derived class. Of these methods, the
only one that must be overridden is run( ).It will not be overriding any of Thread’s other methods, it is
probably best simply to implement Runnable. Also, by implementing Runnable, your thread class does not
need to inherit Thread, making it free to inherit a different class.

Creating multiple Threads:


So far, using only two threads: the main thread and one child thread. However, a program can spawn as many
threads as it needs. For example, the following program creates three child threads:
Output:
Thread Priorities:
Two ways exist to determine whether a thread has finished its task or not. First, you can call isAlive( ) on the
thread. This method is defined by Thread, and its general form is shown here:
final boolean isAlive( )
The isAlive( ) method returns true if the thread upon which it is called is still running. It returns false
otherwise.
While isAlive( ) is occasionally useful, the method that more commonly use to wait for a thread to finish is
called join( ), shown here:
final void join( ) throws InterruptedException
This method waits until the thread on which it is called terminates. Its name comes from the concept of the
calling thread waiting until the specified thread joins it. Additional forms of join( ) allow to specify a
maximum amount of time that want to wait for the specified thread to terminate.
Output:
Thread Priorities:
To set a thread’s priority, use the setPriority( ) method, which is a member of Thread. This is its general
form:
final void setPriority(int level)
Here, level specifies the new priority setting for the calling thread. The value of level must be within the
range MIN_PRIORITY and MAX_PRIORITY. Currently, these values are 1 and 10, respectively. To return
a thread to default priority, specify NORM_PRIORITY, which is currently 5. These priorities are defined as
static final variables within Thread.
Obtain the current priority setting by calling the getPriority( ) method of Thread, shown here:
final int getPriority( )

Synchronization:
When two or more threads need access to a shared resource, they need some way to ensure that the resource
will be used by only one thread at a time. The process by which this is achieved is called synchronization
Using Synchronized Methods :
To enter an object’s monitor, just call a method that has been modified with the synchronized keyword. While
a thread is inside a synchronized method, all other threads that try to call it (or any other synchronized method)
on the same instance have to wait.
Output:
To fix the preceding program, to serialize access to call( ). That is, must restrict its access to only one thread
at a time. To do this, you simply need to precede call( )’s definition with the keyword synchronized, as shown
here:

The synchronized Statement:


Interthread Communication:
To avoid polling, Java includes an elegant interprocess communication mechanism via the wait( ), notify( ),
and notifyAll( ) methods. These methods are implemented as final methods in Object, so all classes have
them. All three methods can be called only from within a synchronized context
• wait( ) tells the calling thread to give up the monitor and go to sleep until some other thread enters
the same monitor and calls notify( ) or notifyAll( ).
• notify( ) wakes up a thread that called wait( ) on the same object.
• notifyAll( ) wakes up all the threads that called wait( ) on the same object. One of the threads will
be granted access.
These methods are declared within Object, as shown here: final void wait( )
throws InterruptedException
final void notify( ) final void
notifyAll( )
Output:
after the producer put 1, the consumer started and got the same 1 five times in a row. Then, the producer
resumed and produced 2 through 7 without letting the consumer have a chance to consume them. The proper
way to write this program in Java is to use wait( ) and notify( ) to signal in both directions, as shown here:
Output:

Deadlock:
A special type of error that you need to avoid that relates specifically to multitasking is deadlock, which
occurs when two threads have a circular dependency on a pair of synchronized objects.
Deadlock is a difficult error to debug for two reasons:
• In general, it occurs only rarely, when the two threads time-slice in just the right
way.
• It may involve more than two threads and two synchronized objects.
Output:

Suspending, resuming and Stopping Threads using


Multithreading:
Aprogram used suspend( ), resume( ), and stop( ), which are methods defined by Thread, to pause, restart,
and stop the execution of a thread.
The resume( ) method is also deprecated. It does not cause problems, but cannot be used without the suspend(
) method as its counterpart. The stop( ) method of the Thread class. The trouble is that stop( ) causes any
lock the calling thread holds to be released. Thus, the corrupted data might be used by another thread that is
waiting on the same lock.

The following example illustrates how the wait( ) and notify( ) methods that are inherited from Object can
be used to control the execution of a thread. Let us consider its operation. The NewThread class contains a
boolean instance variable named suspendFlag, which is
used to control the execution of the thread. It is initialized to false by the constructor. The run( ) method
contains a synchronized statement block that checks suspendFlag. If that variable is true, the wait( ) method
is invoked to suspend the execution of the thread. The mysuspend( ) method sets suspendFlag to true. The
myresume( ) method sets suspendFlag to false and invokes notify( ) to wake up the thread. Finally, the main(
) method has been modified to invoke the mysuspend( ) and myresume( ) methods.
Obtaining a Thread’s State:
The current state of a thread by calling the getState( ) method defined by Thread. It is shown here:
Thread.State getState( )
It returns a value of type Thread.State that indicates the state of the thread at the time at which the call
was made.
State is an enumeration defined by Thread.
Here are the values that can be returned by getState( ):
Thread states:
Given a Thread instance, use getState( ) to obtain the state of a thread. For example, the following sequence
determines if a thread called thrd is in the RUNNABLE state at the time getState( ) is called:

It is important to understand that a thread’s state may change after the call to getState( ). Thus, depending on
the circumstances, the state obtained by calling getState( ) may not reflect the actual state of the thread only
a moment later.

You might also like