Java Unit 3
Java Unit 3
Java Unit 3
All exception and errors types are sub classes of class Throwable, which is base class
of hierarchy.
Error:
An Error indicates serious problem that a reasonable application should not
try to catch.Error is irrecoverable
for e.g. OutOfMemoryError, VirtualMachineError, AssertionError etc.
Exception:
An exception is an unwanted or unexpected event, which occurs during the
execution of a program i.e at run time that disrupts the normal flow of the
program’s instructions
Types of Java Exceptions:
⮚ checked Exceptions
⮚ unchecked Exception
1
⮚ Checked Exception:
● The classes which are directly inherit from Throwable class ,which are
checked at Compilation Process are known as checked exceptions.
● Checked exceptions are checked at compile-time.
⮚ Unchecked Exception
● The classes which are inherit from Throwable classes ,which are
occurred at Runtime(Execution) Process are known as unchecked
exceptions.
● Unchecked exceptions are not occurred at checked at compile-time, but
they are checked at runtime are also known as Runtime Exceptions
CHECKE
EXCEPTIONS DESCRIPTION UNCHECKED
D
Arithmetic errors
ArithmeticException such as a divide - YES
by zero
Arrays index is
ArrayIndexOutOfBoundsEx
not within - YES
ception
array.length
Related Class not
ClassNotFoundException YES -
found
InputOuput field
IOException YES -
not found
Illegal argument
IllegalArgumentException when calling a - YES
method
One thread has
InterruptedException been interrupted YES -
by another thread
2
Nonexistent
NoSuchMethodException YES -
method
Invalid use of null
NullPointerException - YES
reference
Invalid string for
NumberFormatException conversion to - YES
number
Exception Handling
Java exception handling is managed via five keywords: try, catch, throw,
throws, and finally.
Exception Description
Keyword
Try The "try" keyword is used to specify a block where we
should place exception code. The try block must be
followed by either catch or finally. It means, we can't use
try block alone.
Catch The "catch" block is used to handle the exception. It must
be preceded by try block which means we can't use catch
block alone. It can be followed by finally block later.
finally The "finally" block is used to execute the important code of
the program. It is executed whether an exception is
handled or not.
Throw We know that if any exception occurs, an exception object
is getting created and then Java runtime starts processing
to handle them. To manually throw an exception, use the
keyword throw. The throw keyword is mainly used to
throw custom exceptions.
throws The "throws" keyword is used to declare exceptions. It
doesn't throw an exception. It specifies that there may
3
occur an exception in the method. It is always used with
method signature.
For Example:
class test
{
public static void main(String args[])
{
int a=10,b=0,c;
try
{
c=a/b;
System.out.println(“result=”+c);
}
catch (ArithmeticException e)
{
System.out.println(“divide by Zero”);
}
System.out.println(“After try Catch Block”);
}
}
4
Uncaught exceptions:
If Exception handling is not Provided , then in a java application the program
terminates automatically after printing the default exception message.
class Exc0 {
public static void main(String args[]) {
int d = 0;
int a = 42 / d;
}
}
In this example, we haven’t supplied any exception handlers of our own, so the
exception is caught by the default handler provided by the Java run-time
System.
Any exception that is not caught by your program will ultimately be processed
by the default handler. The default handler displays a string describing the
exception, prints a stack trace from the point at which the exception occurred,
and terminates the program.
The stack trace will always show the sequence of method invocations that led
up to the error.
● First, it allows you to fix the error. Second, it prevents the program from
automatically terminating.
5
● To guard against and handle a run-time error, simply enclose the code
that you want to monitor inside a try block. Immediately following the
try block, include a catch clause that specifies the exception type that
you wish to 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:
Example:
class Exc2 {
public static void main(String args[]) {
int d, a;
try { // monitor a block of code.
d = 0;
a = 42 / d;
System.out.println("This will not be printed.");
}
catch (ArithmeticException e)
{ // catch divide-by-zero error
System.out.println("Division by zero.");
}
System.out.println("After try-catch statement.");
}
}
Output:
Division by zero.
After try-catch statement.
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.
Once the catch statement has executed, program control continues with the
next line in the program following the entire try/catch mechanism.
6
In some cases, more than one exception could be raised by a single piece of
code. To handle this type of situation, you can specify two or more catch
clauses, each catching a different type of exception.
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println("Array index oob: " + e);
}
}
}
This program will cause a division-by-zero exception if it is started with no
commandline 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].
C:\>java MultiCatch
a=0
Divide by 0: java.lang.ArithmeticException: / by zero
7
After try/catch blocks.
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.
This continues until one of the catch statements succeeds, or until all of the
nested try statements are exhausted.
If no catch statement matches, then the Java run-time system will handle the
exception. Here is an example that uses nested try statements:
class NestTry {
public static void main(String args[]) {
try {
int a = 0;
int b = 42 / a;
System.out.println("a = " + a);
try{
int c[] = { 1 };
c[42] = 99; // generate an out-of-bounds exception
}
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("Array index out-of-bounds: " + e);
}
} catch(ArithmeticException e) {
System.out.println("Divide by 0: " + e);
}
}
}
As you can see, this program nests one try block within another. The program
works as follows.
8
When you execute the program, a divide-by-zero exception is generated by the
outer try block. An array boundary exception is generated from within the
inner try block.
Using Throw:
Syntax:
throw new ThrowableInstance(parameter);
Forexample:
Exception is a sub-class of Throwable and user defined exceptions typically
extend Exception class.
example:
9
{
System.out.println(e.getMessage());
}
}
public static void main(String args[])
{
positiveNumberCheck(-10);
}
}
Using throws:
The Java throws keyword is used to declare an exception. It gives an
information to the programmer that there may occur an exception so it is
better for the programmer to provide the exception handling code so that
normal flow can be maintained.
This Exception Handling is mainly used to handle the checked exceptions. If
there occurs any unchecked exception such as NullPointerException, it is
programmers fault that he is not performing check up before the code being
used.
Syntax:
return_type method_name() throws exception_class_name
{
//method code
}
Example:
class MyException extends Exception {
public MyException(String msg){
//super(msg);
System.out.println(msg);
}
}
10
public static void main(String[] args)
{
try{
positiveNumberCheck(-10);
}
catch(MyException e)
{
System.out.println(e.getMessage());
}
}
}
Using finally
Java finally block is a block that is used to execute important code such as
closing connection, stream etc.
Java finally block is always executed whether exception is handled or not.
Java finally block follows try or catch block.
class TestFinallyBlock{
public static void main(String args[]){
try
{
int data=25/0;
System.out.println(data);
}
catch(ArithmeticException e)
{
System.out.println(e);
}
finally
{
System.out.println("finally block is always executed");
}
System.out.println("rest of the code...");
}
}
Output:
java.lang.ArithmeticException: / by zero
finally block is always executed
rest of the code...
11
Inside the standard package java.lang, Java defines several exception classes.
The most general of these exceptions are subclasses of the standard type
RuntimeException.
Java defines several other types of exceptions that relate to its various class
libraries.
12
creating own exception sub classes.
If you are creating your own Exception that is known as custom exception or user-
defined exception. Java custom exceptions are used to customize the exception
according to user need.
class InvalidAgeException extends Exception{
InvalidAgeException(String s){
super(s);
}
}
class TestCustomException1{
}
System.out.println("rest of the code...");
} }
Threads
13
What Is a Thread?
1. Process-based Multitasking
2. Thread-based Multitasking.
14
Differences between thread-based multitasking and process-
based Multitasking.
Threads share same address Process requires its own address space.
space.
Thread is a smaller unit Program is a bigger unit.
In thread based multitasking In process based multitasking two or more
two or more threads can be run processes and programs can be run
concurrently. concurrently.
One thread can pause without stopping other parts of your program. For
example, the idle time created when a thread reads data from a network or
waits for user input can be utilized elsewhere.
A thread can be in one of the five states. According to sun, there is only 4
states in thread life cycle in java new, runnable, non-runnable and
terminated. There is no running state.
The life cycle of the thread in java is controlled by JVM. The java thread states
are as follows:
● New Born
● Runnable
● Running
● Blocked
● Dead
16
Following are the stages of the life cycle –
New Born: Whenever a new thread is created, it is always in the new state. For a thread
in the new state, the code has not been run yet and thus has not begun its execution.
Active: When a thread invokes the start() method, it moves from the new state to the
active state. The active state contains two states within it: one is runnable, and the other
is running.
o Runnable: A thread, that is ready to run is then moved to the runnable state. In
the runnable state, the thread may be running or may be ready to run at any
given instant of time. It is the duty of the thread scheduler to provide the thread
time to run, i.e., moving the thread the running state.
A program implementing multithreading acquires a fixed slice of time to each
individual thread. Each and every thread runs for a short span of time and when
that allocated time slice is over, the thread voluntarily gives up the CPU to the
other thread, so that the other threads can also run for their slice of time.
Whenever such a scenario occurs, all those threads that are willing to run, waiting
for their turn to run, lie in the runnable state. In the runnable state, there is a
queue where the threads lie.
o Running: When the thread gets the CPU, it moves from the runnable to the
running state. Generally, the most common change in the state of a thread is
from runnable to running and again back to runnable.
17
Blocked or Waiting: Whenever a thread is inactive for a span of time (not permanently) then,
either the thread is in the blocked state or is in the waiting state.
For example, a thread (let's say its name is A) may want to print some data from the
printer. However, at the same time, the other thread (let's say its name is B) is using the
printer to print some data. Therefore, thread A has to wait for thread B to use the
printer. Thus, thread A is in the blocked state. A thread in the blocked state is unable to
perform any execution and thus never consume any cycle of the Central Processing Unit
(CPU). Hence, we can say that thread A remains idle until the thread scheduler
reactivates thread A, which is in the waiting or blocked state.
When the main thread invokes the join() method then, it is said that the main thread is
in the waiting state. The main thread then waits for the child threads to complete their
tasks. When the child threads complete their job, a notification is sent to the main
thread, which again moves the thread from waiting to the active state.
If there are a lot of threads in the waiting or blocked state, then it is the duty of the
thread scheduler to determine which thread to choose and which one to reject, and the
chosen thread is then given the opportunity to run.
Timed Waiting: Sometimes, waiting for leads to starvation. For example, a thread (its
name is A) has entered the critical section of a code and is not willing to leave that
critical section. In such a scenario, another thread (its name is B) has to wait forever,
which leads to starvation. To avoid such scenario, a timed waiting state is given to
thread B. Thus, thread lies in the waiting state for a specific span of time, and not
forever. A real example of timed waiting is when we invoke the sleep() method on a
specific thread. The sleep() method puts the thread in the timed wait state. After the
time runs out, the thread wakes up and start its execution from when it has left earlier.
Terminated: A thread reaches the termination state because of the following reasons:
o When a thread has finished its job, then it exists or terminates normally.
o Abnormal termination: It occurs when some unusual events such as an
unhandled exception or segmentation fault.
A terminated thread means the thread is no more in the system. In other words, the
thread is dead, and there is no way one can respawn (active after kill) the dead thread.
Creating threads:
18
In Java, an object of the Thread class can represent a thread. Thread can be
implemented through any one of two ways:
1.Thread class:
Thread class provide constructors and methods to create and perform
operations on a thread.Thread class extends Object class and implements
Runnable interface.
Constructors of Thread class
1. Thread()
This constructor creates a thread object having no predefined arguments.
2. Thread(String name)
This constructor creates a thread object having String argument.
3. Thread(Runnable r)
This constructor creates a thread object having argument r of type runnable
4. Thread(Runnable r,String name)
This constructor creates a thread object having two arguments of String and
Runnable type.
To create a thread is to create a new class that extends Thread, then override
the run() method and then to create an instance of that class. The run()
method is what is executed by the thread after you call start().
Here is an example of creating a Java Thread subclass:
public class MyClass extends Thread {
19
public void run(){
System.out.println("MyClass running");
}
}
To create and start the above thread you can do so like this:
MyClass t1 = new MyClass ();
T1.start();
When the run() method executes it will print out the text " MyClass running
".
So far, we have been using only two threads: the main thread and one child
thread. However, our program can affect as many threads as it needs. Let's
see how we can create multiple threads.
20
This method returns the state of the calling thread.
13. public boolean isAlive():
This method returns true if the thread is alive, else returns false.
14. public void yield():
This method pauses the currently executing thread temporarily and allows
other threads to execute.
15. public void suspend():
This method is used to put the thread in suspended state.
16. public void resume():
This method is used to resume the suspended thread.
17. public void stop():
This method is used to stop the running thread.
18. public boolean isDaemon():
This method returns true if the thread is a daemon thread, else returns false.
19. public void setDaemon(boolean b):
This method marks the thread as daemon or user thread.
20. public void interrupt():
This method interrupts the running thread.
21. public boolean isInterrupted():
This method returns true if the thread has been interrupted, else return
false.
22. public static boolean interrupted():
This method returns true if the current thread has been interrupted, else
return false.
21
Output:thread is running... {
System.out.println(s);
}
}
public class RunThread
{
public static void main(String
args[])
{
MyThread m1=new
MyThread("Thread started....");
}
}
Output:
Thread started....
22
public static void main(String args[]){
System.out.println("Thread Name :"
+Thread.currentThread().getName());
Mythread m1=new Mythread("My Thread 1");
Mythread m2=new Mythread("My Thread 2");
}
}
Output:
Thread Name :main
Thread Name :My Thread 2
Thread Name :My Thread 1
Thread Name :My Thread 1
Thread Name :My Thread 2
Thread Name :My Thread 1
Thread Name :My Thread 2
Thread Name :My Thread 1
Thread Name :My Thread 2
Thread Name :My Thread 2
Thread Name :My Thread 1
Runnable interface:
The Runnable interface should be implemented by any class whose
instances are intended to be executed by a thread. Runnable interface have
only one method named run().
The easiest way to create a thread is to create a class that implements the
Runnable interface.
Inside run( ), we will define the code that constitutes the new thread.
Example:
23
To execute the run() method by a thread, pass an instance of MyClass to a
Thread in its constructor (A constructor in Java is a block of code similar to
a method that's called when an instance of an object is created). Here is how
that is done:
When the thread is started it will call the run() method of the MyClass
instance instead of executing its own run() method. The above example
would print out the text "MyClass running ".
Example2:
}
public void run() {
System.out.println(s);
}
}
24
public class RunableThread{
public static void main(String args[]) {
}
Output: Thread started....
t.start();
}
Output:
Thread Name :main
Thread Name :My Thread 1
Thread Name :My Thread 2
25
Thread Name :My Thread 1
Thread Name :My Thread 2
Thread Name :My Thread 2
Thread Name :My Thread 1
Thread Name :My Thread 2
Thread Name :My Thread 1
Thread Name :My Thread 2
Thread Name :My Thread 1
Using sleep():
System.out.println(i);
}
}
t1.start();
t2.start();
}
}
Output:
1
1
2
2
3
3
4
4
26
Thread priority in java
A thread is a part or entity of a process that is scheduled for execution.
ThreadName.setPriority(int number);
Example:
27
class B extends Thread
{
public void run()
{
System.out.println("Thread B strated");
for(int i=0;i<=5;i++)
{
System.out.println("For thread B = "+i);
}
System.out.println("Exit from Thread B");
}
synchronizing threads
When we start two or more threads within a program, there may be a situation
when multiple threads try to access the same resource and finally they can
produce unforeseen result due to concurrency issues. For example, if multiple
threads try to write within a same file then they may corrupt the data because
one of the threads can override data or while one thread is opening the same
file at the same time another thread might be closing the same file.
So there is a need to synchronize the action of multiple threads and make sure
that only one thread can access the resource at a given point in time. This is
implemented using a concept called monitors. Each object in Java is
associated with a monitor, which a thread can lock or unlock. Only one thread
at a time may hold a lock on a monitor.
All other threads attempting to enter the locked monitor will be suspended
until the first thread exits the monitor. These other threads are said to be
waiting for the monitor. A thread that owns a monitor can reenter the same
monitor if it so desires.
Synchronization in java is the capability to control the access of multiple
threads to any shared resource,by using synchronized blocks. You keep
shared resources within this block. Following is the general form of the
synchronized statement −
Syntax
synchronized(objectidentifier) {
// Access shared variables and other shared resources
}
Here, the objectidentifier is a reference to an object whose lock associates
with the monitor that the synchronized statement represents.
29
Java Synchronization is better option where we want to allow only one thread
to access the shared resource.
Mutual Exclusive
Mutual Exclusive helps keep threads from interfering with one another while
sharing data. This can be done by three ways in java:
1. by synchronized method
2. by synchronized block
3. by static synchronization
}
}
}
class MyThread2 extends Thread{
Table t;
MyThread2(Table t){
this.t=t;
30
}
public void run(){
t.printTable(100);
}
}
class TestSynchronization1{
public static void main(String args[]){
Table obj = new Table();//only one object
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj);
t1.start();
t2.start();
}
}
Output:
5
100
10
200
15
300
20
400
25
500
Java synchronized method
31
class Table{
synchronized void printTable(int n){//synchronized method
for(int i=1;i<=5;i++){
System.out.println(n*i);
try{
Thread.sleep(400);
}catch(Exception e){System.out.println(e);}
}
}
}
}
class MyThread2 extends Thread{
Table t;
MyThread2(Table t){
this.t=t;
}
public void run(){
t.printTable(100);
}
}
Output:
5
10
32
15
20
25
100
200
300
400
500
Synchronized block in java
Synchronized block can be used to perform synchronization on any
specific resource of the method.
Suppose you have 50 lines of code in your method, but you want to
synchronize only 5 lines, you can use synchronized block.
If you put all the codes of the method in the synchronized block, it will
work same as the synchronized method.
class Table{
33
class MyThread2 extends Thread{
Table t;
MyThread2(Table t){
this.t=t;
}
public void run(){
t.printTable(100);
}
}
public class TestSynchronizedBlock1{
public static void main(String args[]){
Table obj = new Table();//only one object
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj);
t1.start();
t2.start();
}
}
Output:
5
10
15
20
25
100
200
300
400
500
34
}
Deadlock in java
Deadlock in java is a part of multithreading. Deadlock can occur in a situation
when a thread is waiting for an object lock, that is acquired by another thread
and second thread is waiting for an object lock that is acquired by first thread.
35
Since, both threads are waiting for each other to release the lock, the condition
is called deadlock.
Deadlock describes a situation where two or more threads are blocked forever,
waiting for each other. Deadlock occurs when multiple threads need the same
locks but obtain them in different order. A Java multithreaded program may
suffer from the deadlock condition because the synchronized keyword causes
the executing thread to block while waiting for the lock, or monitor, associated
with the specified object.
For example, consider the classic queuing problem, where one thread is
producing some data and another is consuming it. To make the problem more
interesting, suppose that the producer has to wait until the consumer is
finished before it generates more data. In a polling system, the consumer would
waste many CPU cycles while it waited for the producer to produce. Once the
producer was finished, it would start polling, wasting more CPU cycles waiting
for the consumer to finish, and so on. Clearly, this situation is undesirable.
36
● wait()
● notify()
● notifyAll()
wait() method
Causes the current thread to wait until another thread invokes the notify().
Method Description
public final void wait()throws waits until object is notified.
InterruptedException
public final void wait(long timeout)throws waits for the specified
InterruptedException amount of time.
Wakes up all the threads that called wait( ) on the same object.
Example :
class Customer{
int amount=10000;
System.out.println("going to withdraw...");
if(amount<amt){
37
try{
wait();
catch(Exception e){ }
amount=amount-amt;
System.out.println("withdraw completed...");
System.out.println("going to deposit...");
amount=amount+amt;
notify();
Customer c;
Producer(Customer c)
this.c=c;
new Thread(this,”Producer”).start();
c.deposit(10000);
38
class Consumer implements Runnable
Customer c;
Consumer(Customer c)
this.c=c;
new Thread(this,”Consumer”).start();
c.withdraw(15000);
new Producer(c);
new Consumer(c);
output:
going to withdraw...
going to deposit...
deposit completed...
withdraw completed..
39