Sei sulla pagina 1di 46

99

String Handling
String manipulation is the most common part of many Java programs. Strings represent a
sequence of characters. A Java string is an instantiated object of the String class. Java strings, as
compared to C strings, are more reliable and predictable. A Java string is not a character array
and is not NULL terminated. String is a class in java.lang package.

Creating Strings:

1. We can declare a String variable and directly store a String literal using assignment
operator.

String str; // declaring the string type variable

Str=”Hello java”; //assign a group of characters to it

String str = “Hello java”

In this case JVM creates an object and stores “hello java” in that object. This object is referenced
by the variable “str”.

2. We can create an object to String class by allocating memory using new Operator.
This is like creating an object to any class.
String s1 = new String ("Java");

3. We can create a String by converting the character array into strings.

char arr[ ] = { 'p','r','o',’g’,’r’,’a’,’m’};

String s2 = new String (arr);

Now the String object contains the String “program”. This means all the characters of the array
are copied into the String. We can also create a String by passing array name and specifying
which characters we need:

String s3 = new String ( arr, 2, 3 );


Here starting from 2nd character a total of 3 characters are copied into String s3.
100

String Methods: (Methods of String class)


Strings represent a sequence of characters. A Java string is an instantiated object of the String
class. Java strings, as compared to C strings, are more reliable and predictable. A Java string is
not a character array and is not NULL terminated. String is a class in java.lang package and the
java strings are immutable.

1. String concat (String str)


The “concat” method concatenates or joins two strings and returns a third string as a result. The
same concatenation can be done by using “+” operator which is called string concatenation
operator.

2. length ( )
The length of a string is the number of characters that it contains. To obtain this value, call the
length( ) method shown here:
int length( );

3. charAt()
This method returns the character at the specified location. Suppose we call this method as
s1.charAt(5) , then it gives the character at 5th index in the string s1.
Syntax: char charAt(int where);
Here, where is the index of the character that you want to obtain.

4. compareTo(String str)
This method is useful to compare two strings and to know which string is bigger or smaller or
equal.
Syntax: int compareTo ( String str );
Here, str is the String being compared with the invoking String. The result of the comparison is
returned and is interpreted as shown below:

Value Meaning

Less than zero  The invoking string is less than str. Greater
than zero  The invoking string is greater than str. Zero
The two strings are equal

5. equals ( )
This method returns true if the two strings are same, otherwise false. This is case sensitive.
Syntax:
boolean equals(Object str);

6. equalsIgnoreCase (String str)


Same as preceding but it performs case insensitive comparison. Syntax:
boolean equalsIgnoreCase (String str)

7. replace (char oldchar, char newchar)


Returns a new String that is obtained by replacing all characters old char in String with newchar.
Syn:
String replace (char original, char replacement);

8. substring (int beginIndex, int endIndex)


101

Returns a new String consisting of all characters from beginIndex until the endIndex.
Syn: String substring(int startIndex)

9. String toUpperCase()
This method converts all of the characters in this String to upper case using the Syntax:
String toUpperCase( )

10. String toLowerCase()


This method converts all of the characters in this String to lower case Syntax:
String toLowerCase( )

Program: To sort the string in Alphabetical order


//StringOrdering.java
//Alphabetical ordering of strings
class StringOrdering
{
public static void main(String args[])
{
String names[]={"india","usa","australia","africa","japan"};
int size=names.length;
String temp;
for(int i=0;i<size;i++)
{
for(int j=i+1;j<size;j++)
{
if(names[j].compareTo(names[i])<0)
{
temp=names[i];
names[i]=names[j];
names[j]=temp;
}
}
}
for(int i=0;i<size;i++)
System.out.println(names[i]);
}
}
Output:
africa
australia
india
japan
usa

StringBuffer Class :
StringBuffer is a peer class of String. While String creates string of fixed length, StringBuffer
creates strings of flexible length that can be modified in terms of both length and content. We can
insert characters and substrings in the middle of a string, or append another string to the end.
Below, there are some of methods that are frequently used in string manipulations.
Important methods of StringBuffer class
102

append(String s):
is used to append the specified string with this string. The append() method is overloaded like
append(char), append(boolean), append(int), append(float), append(double) etc.

insert(int offset, String s):


is used to insert the specified string with this string at the specified position. The insert() method
is overloaded like insert(int, char), insert(int, boolean), insert(int, int), insert(int, float), insert(int,
double) etc.

replace(int startIndex, int endIndex, String str):


is used to replace the string from specified startIndex and endIndex.

delete(int startIndex, int endIndex):


is used to delete the string from specified startIndex and endIndex.

reverse(): is used to reverse the string.

capacity():it is used to return the current capacity.

ensureCapacity(int minimumCapacity):
is used to ensure the capacity at least equal to the given minimum.

charAt(int index):
is used to return the character at the specified position.

length():
is used to return the length of the string i.e. total number of characters.

substring(int beginIndex):
is used to return the substring from the specified beginIndex.

substring(int beginIndex, int endIndex):


is used to return the substring from the specified beginIndex and endIndex.

The following program illustrates the concept of StringBuffer class in java.


Program:
class StringBufferConst
{
public static void main(String args[])
{
StringBuffer buff1 = new StringBuffer();
System.out.println("Length is: "+buff1.length());
System.out.println("Capacity is: "+buff1.capacity());

StringBuffer buff2 = new StringBuffer(20);


System.out.println("Length is: "+buff2.length());
System.out.println("Capacity is: "+buff2.capacity());

StringBuffer buff3 = new StringBuffer("hello");


System.out.println("Length is: "+buff3.length());
System.out.println("Capacity is: "+buff3.capacity());
103

CharSequence seq = "Hai";


StringBuffer buff4 = new StringBuffer(seq);
System.out.println("Length is: "+buff4.length());
System.out.println("Capacity is: "+buff4.capacity());
}
}
Output:

Length is: 0
Capacity is: 16
Length is: 0
Capacity is: 20
Length is: 5
Capacity is: 21
Length is: 3
Capacity is: 19

--xxx—

Vectors in Java
Vector is a class contained in java.util package. It is used to create a generic dynamic array known
as vector that can hold objects of any type and any number. The objects do not have to be
homogeneous.
The vectors are created as follows
Vector vect=new Vector(); // declaring without size.
Vector list=new Vector(3);// declaring with size 3.
A Vector without size can accommodate an unknown number of items.
When a size is specified, this can be overlooked and a different number of items may be
put into the vector.

Advantages of Vectors over Arrays


1. It is convenient to use vectors to store objects.
2. A vector can be used to store a list of objects that may vary in size.
3. We can add and delete objects from the list as and when required.

A major constraint in using vectors is that we cannot directly store simple data type in a vector,
we only store objects. Therefore, we need to convert simple types to objects. This can be done
using the wrapper classes.

The vector class supports a number of methods that can be used to manipulate the vectors
created.
The following table contains the important methods of a vector class.

Method call Task Performed


List.addElement(item) Adds the item specified to the list at the end.
List.elementAt(10) Gives the name of the 10th object.
List.size() Gives the number of objects present.
List.removeElement(item) Removes the specified item from the list.
104

List.removeElementAt(n) Removes the item stored in the nth position of the list.
List.removeAllElements() Removes all the elements in the list.
List.copyInto(array) Copies all the elements from list to array.
List.insertElementAt(item,n) Insert the item at the nth position.

The following program illustrates the concept of Vectors in java.


Aim: To work with the Vectors and arrays in java Program : Wite a program to read
some names into the vector and print them back
import java.util.*;
class Vector_ex
{
public static void main(String args[ ])
{
Vector v= new Vector( );
Scanner sc = new Scanner(System.in);
int i;
System.out.println("enter 3 names ");
for(i=0;i<3 ;i++)
v.addElement(sc.next( ));
System.out.println("The names are ");

for(i=0;i<3 ;i++)
System.out.println(v.elementAt(i));
}
}
Output:
enter 3 names
hari giri siri
The namesare
hari giri siri

Wrapper classes
The Vectors cannot handle the primitive data types like int, float, long , char and double. Primitive
data types may be converted into object types by using the wrapper classes contained in the
java.lang package. The following table shows the simple data types and their corresponding
wrapper classes.

Simple Type Wrapper Class


boolean Boolean
char Character
double Double
float Float
int Integer
long Long

The wrapper classes have a number of unique methods for handling primitive data types and
objects. They are listed in the following table.

Constructor calling Conversion Action


Integer intval=new Integer(i); Primitive integer to Integer Object
Float floatval=new Float(f); Primitive float to Float Object
105

Double dobval=new Double(d); Primitive double to Double Object


Long longval=new Long(l); Primitive long to Long Object

The following table shows the methods to conver Object numbers to Primitive Numbers using
typeValue() method

Method Calling Conversion Action


int i=intval.intValue(); Object to Primitive integer
float f=floatval.flaotValue(); Object to primitive float
long l=longval.longValue(); Object to primitive long
double d=dobval.doubleValue(); Object to primitive double

The following table shows the methods to convert numbers to strings using toString() method

Method Calling Conversion Action


str=Integer.toString(i); Primitive integer to string
str=Float.toString(f); Primitive float to string
str=Double.toString(d); Primitive double to string
str=Long.toString(l); Primitive long to string

The following table shows the methods to convert String objects to numeric Obejcts using the
static method ValueOf().

Method Calling Conversion Action


dobval=Double.ValueOf(str); Converts strings to Double object
floatval=Float.ValueOf(str); Converts strings to Float object
intval=Integer.ValueOf(str); Converts strings to Integer object
longval=Long.ValueOf(str); Converts strings to Long object

The following table shows the methods to convert Numeric Strings to Primitive Numbers using
Parsing Methods.

Method Calling Conversion Action


int i=Integer.parseInt(str); Converts string to primitive integer
long l=Long.parseLong(str); Converts string to primitive long

--xxx—

Abstract Classes and Methods in Java


Abstract Class –

A class that is declared with abstract keyword, is known as abstract class in java. It can
have abstract and non-abstract methods (method with body). It needs to be extended and
its method implemented. It cannot be instantiated.
106

Eg: abstract class A

Abstract Methods –

A method that is declared as abstract and does not have implementation is known as
abstract method.

abstract void printStatus();//no body and abstract

Understanding the real use of Abstract Class & Abstract Methods –

In this example, we have a Shape super class which is inherited by 3 sub classes – Rectangle,
Triangle and Circle. The task here is to have 1 Area() method in the parent/super class and is
inherited by all 3 child/sub classes.

However, every child class has its own definition to calculate area as the area formula for each
shape is different. Also, since our parent class shape is not known, we cannot have a valid method
definition in the parent class. So this is where we can use Abstract class concept and make the
Area() method in the parent class as abstract. Once we inherit from the Shape class, the
subclasses can have their respective implementations done according to their needs.

The rules for abstract methods and abstract classes are:


107

--xx—

INTERFACES
An interface in java is a blueprint of a class. It has static constants and abstract methods.
The interface in java is a mechanism to achieve abstraction. There can be only abstract
methods in the java interface not method body. It is used to achieve abstraction and multiple
inheritance in Java.

Java Interface also represents IS-A relationship. It cannot be instantiated just like abstract
class.

There are mainly three reasons to use interface. They are given below.
o It is used to achieve abstraction.
o By interface, we can support the functionality of multiple inheritance.
o It can be used to achieve loose coupling.

The relationship between classes and interfaces

As shown in the figure given below, a class extends another class, an interface extends another
interface, but a class implements an interface.
108

Declaration of interface:

An interface is declared by using the interface keyword. It provides total abstraction; means all
the methods in an interface are declared with the empty body, and all the fields are public, static
and final by default. A class that implements an interface must implement all the methods
declared in the interface.

Syntax:
interface <interface_name>{

// declare constant fields


// declare methods that abstract
// by default.
}
Eg: interface ItemConstants
{
int code=1001;
String name=”Fan”;
Void display();
}

The java compiler adds public and abstract keywords before the interface method
and public, static and final keywords before data members.

Extending Interfaces

Like classes, interfaces can also be extended. That is, an interface can be sub interfaced from
other interfaces. The new sub interface will inherit all the members of the super interface in the
manner similar to sub classes. This is achieved using the keyword extends as shown in below.

interface name2 extends name1


{
Body of name2;
}

Consider the following example,

interface ItemConstants
{
int code=1001;
String name=”Fan”;
}
interface Item extends ItemConstants
{
void display();
}
109

Implementing Interfaces

Once an interface has been defined, one or more classes can implement that interface. To
implement an interface, include the implements clause in a class definition, and then create the
methods defined by the interface. The general form of a class that includes the implements
clause looks like this:

class class_name implements interface_name

Body of class name

Here the class class_name “implements” the interface interface_name.

Eg: class Display implements Item


{
public void display()
{
System.out.println(code + “ “ + name);
}
}

When a class implements more than one interface, they are separated by a comma. The
implementation of interfaces can take various forms as illustrated below.

The following program illustrates the concept of interfaces in java.


110

//InterfaceTest.java

interface Area //Interface defined

final static float pi=3.14f;

float compute(float x,float y);

class Rectangle implements Area

public float compute(float x, float y)

return (x*y);

class Circle implements Area

public float compute(float x,float y)

return (pi*x*y);

class InterfaceTest

public static void main(String args[])

Rectangle rect=new Rectangle();

Circle cir=new Circle();

Area area;
111

area=rect;

System.out.println("Area of Rectangle=" + area.compute(10,20));

area=cir;

System.out.println("area of circle=" + area.compute(10,10));

Output:

Accessing Interface Variables

Interfaces can also be used to declare a set of constants that can be used in different classes.
The constant values will be available to any class that implements the interface. The values can
be used in any method, as part of any variable declaration, or anywhere where we can use a
final value.

Example

interface A
{
int m=10;
int n=50;
}
class B implements A
{
void method(int size)
{
------------------
------------------
if(size<n)
-----------------
}
}

--xxx--

Multiple inheritance in Java by interface


112

Multiple Inheritance in Java is nothing but one class extending more than one
class. Java does not have this capability. As the designers considered that multiple inheritance
will to be too complex to manage, but indirectly you can achieve Multiple Inheritance in
Java using Interfaces.

As in Java we can implement more than one interface we achieve the same effect using
interfaces.

Flow Diagram

Conceptually Multiple Inheritance has to be like the below diagram, ClassA and ClassB both
inherited by ClassC. Since it is not supported we will changing the ClassA to
InterfaceA and ClassB to InterfaceB.

Example of Multiple Inheritance

Write a program demonstrate working of Multiple inheretance using Interfaces.


Find the chaild average height using father and mother heights.

interface Father
{
float HT=6.2f;
void height();
}

interface Mother
{
float HT=5.2f;
void height();
}

class Child implements Father, Mother


{
public void height()
{
float ht=(Father.HT+Mother.HT)/2;
113

System.out.println(ht);
}
}

class Multi
{
public static void main(String ar[])
{
Child c=new Child();
c.height();
}
}
Output :
5.7

--xx-
114

Lab work on Examples of multiple inheritance:


Example1:
Write a program demonstrate working of Multiple inheretance using Interfaces.
Find the chaild average height using father and mother heights.

interface Father
{
float HT=6.2f;
void height();
}

interface Mother
{
float HT=5.2f;
void height();
}

class Child implements Father, Mother


{
public void height()
{
float ht=(Father.HT+Mother.HT)/2;
System.out.println(ht);
}
}

class Multi
{
public static void main(String ar[])
{
Child c=new Child();
c.height();
}
}
Output :
5.7

--xx--
Example 2:
interface Printable{
void print();
}

interface Showable{
void show();
}

class A implements Printable,Showable{


115

public void print(){System.out.println("Hello");}


public void show(){System.out.println("Welcome");}

public static void main(String args[]){


A obj = new A();
obj.print();
obj.show();
}
}
Output:Hello
Welcome

Note: Write any one example in Exam

DIFFERENCES BETWEEN CLASSES AND INTERFACES:


Classe Interfaces
s
Classes have instances as variables and Interfaces have instances as abstract
methods
methods with body
and final constants variables.
Inheritance goes with extends keyword Inheritance goes with implements keywords.
The variables can have any access The Variables should be public, static, final
specifier.
Multiple inheritance is not possible It is possible
Classes are created by putting the Interfaces are created by putting the
keyword keyword
class prior to class_name. interface prior to interface_name
Classes contain any type of methods. Interfaces contain abstract methods.
Classes
Interfaces are exhibit the fully abstractions
may or may not provide the abstractions.

Comparison between abstract class and interfaces


abstract class
 An abstract class is a class with one or more abstract methods
 An abstract class contains instance variables & concrete methods in addition to abstract
methods.
 It is not possible to create objects to abstract class by using new operator. But we can
create a reference of abstract class type.
 All the abstract methods of the abstract class should be implemented by its sub
116

classes. If any method is not implemented, then that sub class should be declared as
„abstract‟.
 Abstract class reference can be used to refer to the objects of its sub classes.
 Abstract class references cannot refer to the individual methods of sub classes.
 A class cannot be both „abstract‟ & „final‟.

Interfaces
 An interface is a specification of method prototypes.
 An interface contains zero or more abstract methods. All the methods of interface are
public, abstract by default.
 An interface may contain variables which are by default public static final.
 Once an interface is written any third party vendor can implement it.
 All the methods of the interface should be implemented in its implementation classes.
 If any one of the method is not implemented, then that implementation class should be
declared as abstract.
 We cannot create an object to an interface. We can create a reference variable to an
interface.
 An interface cannot implement another interface. An interface can extend another
interface. A class can implement multiple interfaces.
117

UNIT-III Multithreaded Programming & Exception Handling

Multithreaded Programming
Multithreading: A thread is nothing but an independent path of execution. It is a smallest
individual task in a program. In java it is possible to execute multiple threads at a time. This
process is called multithreading or multi tasking. Multi threading is very suitable for game and
network application.

Multithreading is a Java feature that allows concurrent execution of two or more parts of a
program for maximum utilization of CPU. Threads are light-weight processes within a process.
Thread is a predefined class prsent in java.lang package.

Any application can have multiple processes (instances). Each of this process can be assigned
either as a single thread or multiple threads.

Types of Threads in Java: There are two types of Threads in java.

1) User Thread : User threads are threads which are created by the application or user. They
are high priority threads. JVM (Java Virtual Machine) will not exit until all user threads finish their
execution. JVM wait for these threads to finish their task. These threads are foreground threads.

2)Daemon Thread : Daemon threads are threads which are mostly created by the JVM. These
threads always run in background. These threads are used to perform some background tasks like
garbage collection etc. These threads are less priority threads. JVM will not wait for these threads
to finish their execution. JVM will exit as soon as all user threads finish their execution. JVM
doesn’t wait for daemon threads to finish their task.
118

Creating Threads:

Creating threads in java is simple. A new thread can created in two ways.
1. By Extending a thread class: define a class which extends Thread class and override its
run () method with the code required by the thread.

2. By implementing Runnable interface: define a class which implements Runnable


interface. The Runnable interface has only one method run( ), that is to be defined in the
method with the code to be executed by the thread.

1. By extending a thread class:

We can make our class runnable by extending the Thread class. It includes the following
steps:
 Declare the class as extending the Thread class.

Class custom_Thread extends Thread

 Implement the run( ) method that is responsible for executing the sequence of code
that the tread will execute.

Public void run( ) {

//do the work this thread was created for

 Create a thread object and call the start( ) method to initiate the thread execution.

Custom_Threadth = new custom_Thread( );

th.start( );

Example:

The following program illustrates the concept of extending the thread class.
class A extends Thread
{
public void run()
{
119

for(int i=1;i<=5;i++)
{
System.out.println("From Thread A: i =" + i);
}
System.out.println("Exiting from the Thread A");
}
}
class B extends Thread
{
public void run()
{
for(int j=1;j<=5;j++)
{
System.out.println("From Thread B: j =" + j);
}
System.out.println("Exiting from the Thread B");
}
}
class ThreadTest
{
public static void main(String args[])
{
A a=new A();
B b=new B();
a.start();
b.start();
System.out.println("Exiting from the main");
}
}

Output:

Extending Thread Class

We can make our class runnable as thread by extending the class java.lang.Thread. This
gives us access to all the thread methods directly. It includes the following steps:

1. Declare the class as extending the Thread class


120

2. Implement the run ( ) method that is responsible for executing the sequence of code that the
thread will execute.

3. Create a thread object and call the start ( ) method to initiate the thread execution.

The following program illustrates the concept of extending the thread class.

class A extends Thread


{
public void run()
{
for(int i=1;i<=5;i++)
{
System.out.println("From Thread A: i =" + i);
}
System.out.println("Exiting from the Thread A");
}
}
class B extends Thread
{
public void run()
{
for(int j=1;j<=5;j++)
{
System.out.println("From Thread B: j =" + j);
}
System.out.println("Exiting from the Thread B");
}
}
class ThreadTest
{
public static void main(String args[])
{
A a=new A();
B b=new B();
a.start();
b.start();
System.out.println("Exiting from the main");
}
}

Output:
121

--xxx--

Thread Life Cycle


During the life time of a thread, there are many states it can enter. They include:

1. Newborn state.

2. Runnable state.

3. Running state.

4. Blocked state.

5. Dead state.

 A thread can be ready to run as soon as it gets the cpu time.

 A running Thread can be suspended, which temporarily suspends its activity.

 A suspended thread can then be resumed allowing it to pick up where it left off.

 At any time a thread can be terminated, which halts its execution immediately.

 Once terminated a thread can not be resumed.


122

New state

When we create a thread object the thread is born and is said to be in new born state. At this
state, we can do only one of the following things.

-->Schedule it for running using start() method

-->Kill it using stop() method. If scheduled, it moves to the runnable state.


123

Runnable (Ready-to-run) state

A thread start its life from Runnable state. A thread first enters runnable state after the invoking
of start() method but a thread can return to this state after either running, waiting, sleeping or
coming back from blocked state also. On this state a thread is waiting for a turn on the

processor .

Running state

A thread is in running state that means the thread is currently executing. There are several ways
to enter in Runnable state but there is only one way to enter in Running state: the scheduler
select a thread from runnable pool.

Blocked

A thread can enter in this state because of waiting for the resources that are hold by another
thread. A blocked thread is considered “not runnable” but not dead and therefore fully qualified to
run again.
124

Dead state

A thread can be considered dead when its run( ) method completes. If any thread comes on this
state that means it cannot ever run again. It is a natural death. We can kill it by sending the stop
message to it at any state thus causing a premature death to it.

--xxx—

Using wait(), notify() and notifyAll()

The Java language includes three important methods that effectively allow one thread to signal
to another. Without this facility, various constructs used in concurrent programming would be
difficult and inefficient to implement, at least prior to Java.

Put simply, this is how signalling between threads works using ‘wait and notify’:

1. We can call the wait() method of any Java object, which suspends the current
thread. The thread is said to be “waiting on” the given object.

2. Another thread calls the notify() method of the same Java object. This “wakes up”
one of the threads waiting on that object.

In some of the following discussion, we’ll use the term wait/notify mechanism, and refer
to the two methods wait() and notify(). However, we’ll see that much of the discussion
includes notifyAll() and we’ll look at when to use the two variants below.

How to use wait/notifty?

The following issues then generally arise:

1.When do you use wait/notify?: we’ll look first at a simple thread pool, then later at thread
coordination;

2.How do you use wait/notify?;

3.when to use notifyAll (which ‘wakes up’ multiple waiting threads as opposed to just one)?
125

4.using timed waits for cases where we don’t want the waiting thread to be allowed to wait
forever.

Example:
Write a JAVA program Producer Consumer Problem
Program:
class A
{
int n;
boolean b=false;
synchronized int get()
{
if(!b)
try
{
wait();
}
Catch(Exception e)
{
System.out.println(e);
}
System.out.println("Got:"+n);
b=false;
notify();
return n;
}

synchronized void put(int n)


{
if(b)
try
{
wait();
}
catch(Exception e)
{
System.out.println(e);
}
this.n=n;
b=true;
System.out.println("Put:"+n);
notify();
}
}

class producer implements Runnable


{
A a1;
Thread t1;
producer(A a1)
{
this.a1=a1;
t1=new Thread(this);
126

t1.start();
}

public void run()

{
for(int i=1;i<=10;i++)
{
a1.put(i);
}
}
}

class consumer implements Runnable


{
A a1;
Thread t1;
consumer(A a1)
{
this.a1=a1;
t1=new Thread(this);
t1.start();
}
public void run()
{
for(int j=1;j<=10;j++)
{
a1.get();
}
}
}

class interdemo
{
public static void main(String args[])
{
A a1=new A();
producer p1=new producer(a1);
consumer c1=new consumer(a1);
}
}
Output:
Put:1
Got:1
Put:2
Got:2
Put:3
Got:3
Put:4
Got:4
Put:5
Got:5
Put:6
127

Got:6
Put:7
Got:7
Put:8
Got:8
Put:9
Got:9
Put:10

Got:10

Using Stop( ), suspend( ), and resume( )

Because threads can become blocked and because objects can have synchronized methods that
prevent threads from accessing that object until the synchronization lock is released, it’s possible
for one thread to get stuck waiting for another thread, which in turn waits for another thread,
etc., until the chain leads back to a thread waiting on the first one.

Thus, there’s a continuous loop of threads waiting on each other and no one can move. This is
called deadlock. The claim is that it doesn’t happen that often, but when it happens to you it’s
frustrating to debug.

There is no language support to help prevent deadlock; it’s up to you to avoid it by careful design.
These are not comforting words to the person who’s trying to debug a deadlocking program.

One change that has been made in Java 1.2 to reduce the possibility of deadlock is the
deprecation of Thread’s stop( ), suspend( ), and resume( ) methods.

Example :
public class JavaSuspendExp extends Thread
{
public void run()
{
for(int i=1; i<5; i++)
{
try
{
// thread to sleep for 500 milliseconds
sleep(500);
System.out.println(Thread.currentThread().getName());
}catch(InterruptedException e){System.out.println(e);}
System.out.println(i);
}
}
public static void main(String args[])
{
// creating three threads
JavaSuspendExp t1=new JavaSuspendExp ();
JavaSuspendExp t2=new JavaSuspendExp ();
128

JavaSuspendExp t3=new JavaSuspendExp ();


// call run() method
t1.start();
t2.start();
// suspend t2 thread
t2.suspend();
// call run() method
t3.start();
}
}

Output:
Thread-0
1
Thread-2
1
Thread-0
2
Thread-2
2
Thread-0
3
Thread-2
3
Thread-0
4
Thread-2
4

Thread Exceptions
That the call to sleep ( ) method is enclosed in a try block and followed by a catch block.
This is necessary because the sleep ( ) method throws an exception, which should be
caught. If we fail to catch the exception, program will not compile.

Java run system will throw IlIegalTheadStateException whenever we attempt to


invoke a method that a thread cannot handle in the given state. For example a sleeping
thread cannot deal with the resume ( ) method because a sleeping thread cannot
receive any instructions. The same is true with the suspend ( ) method when it is used
on a blocked thread.

Whenever we call a thread method that is likely to throw an exception, we have,


to supply an appropriate exception handler to catch it. The catch statement may take
one of the following forms:
129

Catch (ThreadDeath e)
{
...... // Killed thread
}
catch(InterruptedException e)
{
. . . . // Cannot handle it in the current state
}
catchdllegalArgumentException e)
{
.. . . // Illegal Method argument
}
catch(Exception e)
{
.. . . // Any other
}

Thread Priority
In java, each thread is assigned a priority, which effects the order in which it is scheduled for
running. The Threads of the same priority are given equal treatment by the java scheduler and,
therefore, they share the processor on a First-Come, First-Serve basis.

Java permits us to set the priority of a thread using the setPriority() method as follows.

ThreadName.setPriority(Number);

The Number is an integer value to which the threads priority is set. The Thread class defines
several priority constants.

MIN_PRIOITY=1

NORM_PRIORITY=5

MAX_PRIORITY=10

Whenever multiple Threads are ready for execution, the Java system chooses the highest priority
thread and executes it. For a thread of lower priority to gain control, one of the following things
should happen.
1. It stops running at the end of run().
2. It is made to sleep using sleep().
3. It is told to wait using wait().
The following program illustrates the concept of thread priorities in java.
//Program to illustrates the concept of Thread Priority
//ThreadPriority.java
class A extends Thread
{
public void run()
{
System.out.println("Thread A Started....");
130

for(int i=1;i<=5;i++)
{
System.out.println("\t From Thread A : i= " + i);
}
System.out.println("Exit from Thread A");
}
}
class B extends Thread
{
public void run()
{
System.out.println("Thread B Started....");
for(int j=1;j<=5;j++)
{
System.out.println("\t From Thread B : j= " + j);
}
System.out.println("Exit from Thread B");
}
}
class C extends Thread
{
public void run()
{
System.out.println("Thread C Started....");
for(int k=1;k<=5;k++)
{
System.out.println("\t From Thread C : k= " + k);
}
System.out.println("Exit from Thread C");
}
}

class ThreadPriorityDemo
{
public static void main(String args[])
{
A threadA=new A();
B threadB=new B();
C threadC=new C();

threadC.setPriority(Thread.MAX_PRIORITY);
threadB.setPriority(threadA.getPriority()+1);
threadA.setPriority(Thread.MIN_PRIORITY);

System.out.println("Start Thread A");


threadA.start();
System.out.println("Start Thread B");
threadB.start();
System.out.println("Start Thread C");
threadC.start();

System.out.println("Exit from main()");


}
131

Output

--xxx—

Synchronization
When two or more threads access to a shared( common) 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. We can synchronize our code in two ways. Both involve the use of
“synchronized” keyword
1. Synchronized methods
2. Synchronized code blocks

synchronized methods:

We can serialize the access to the methods to only one thread at a time. To do this you simply
need to precede the method’s definition with the keyword synchronized.

synchronized void meth( ) {


132

Some thread work;

When we declare a method synchronized, java creates a “monitor” and hands it over the thread
that calls method first time. As long as the thread holds the monitor, no other thread can enter
the synchronized section of code.

synchronized code blocks:

We use the keyword synchronized indicating the object you want to restrict access to. The general
form is

synchronized (obj)

//statements to be synchronized

}
Syntax:
class A extends Thread
{
synchronized void method()
{
———;
———;
}
}
class B extends Thread
{
synchronized void method()
{
———;
———;
}
}

*Write a program to run two threads one after one by using Synchronizition .

class One
{
synchronized void show()
{
int i;
133

for(i=1;i<=10;i++)
{
System.out.println(i);
try
{
Thread.sleep(1000);
}
catch(Exception e)
{}
}
}
}

class Two extends Thread


{
One o;
Two(One o)
{
this.o=o;
}

public void run()


{
o.show();
}
}

class Syn
{
public static void main(String ar[])
{
One o=new One();
Two t1=new Two(o);
Two t2=new Two(o);
t1.start();
t2.start();
}
}

Ouput:
1
2
3
4
5
6
7
8
9
10
1
2
3
134

4
5
6
7
8
9
10
--xxx—

Implementing Runnable Interface


The Runnable interface declares the run ( ) method that is required for implementing
threads in our programs. To do this, we must perform the steps listed below:

1) Declare the class as implementing the Runnable interface.

2) Implement the run() method

3) call the thread‘s start() method to run the thread.

The following program illustrates the concept of implementing the Runnable Interface in
java.

class A implements Runnable

public void run()

for(int i=1;i<=5;i++)

System.out.println("Thread A : i = " + i);

System.out.println("Exiting from the Thread A");

class RunnableTest

public static void main(String args[])

{
135

A ob=new A();

Thread t=new Thread(ob);

t.start();

System.out.println("Exiting from the main()");

Output

Inter-thread communication
Java supports inter-thread communication using wait(), notify(), 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()

notify() wakes up the first thread that called wait() on the same object.

notifyAll() wakes up all the threads that called wait() on the same object. The highest priority
thread will run first.
136

Exception Handling
Error: An error is a mistake that might lead to produce unexpected result. It may produce in
current output or may terminate the execution of a program in the middle or even it may crash
the system. It is therefore in important to detect and mange the errors that occurs during
execution of a program.

Types of error :

Errors can be classified into three categories.


i. Compile time errors
ii. Run time errors
iii. Logical Errors

Compile Time Errors:


All syntax errors will be detected by the java compiler and therefore these errors are known as
“Compile time errors”. when a compile time error occurs, then the class file will not created.
Therefore, it is necessary to fix all compile time errors before running the program.
eg: class Error1
{
public static void main(String args[])
{
System.out.println(“java”) // missing semicolon
}
}

When we compile the above example program, the java compiler displays the following message
on the screen.
Error1. java:7: ‘;’ expected
System.out.println(“java”)
1error

Most of the compile time errors are due to typing mistakes. The most common problems are:
—Missing semicolons
—Missing brackets in classes and methods
—Misspelling of identifiers and keywords
—Use of undeclared variables etc.

Runtime errors:
Sometimes a program may compile sucessfilly creating the classfile but may not run property.
Such programs may produce wrong results due to wrong logic or invalid input values given by the
user. An error that occur during the execution of a program is known as “exception”.

Most commonly runtime errors are:


—Divide by 0
—Attempting to use a negative size for an array.
—Converting invalid string to a number.
—Typing to illegally change the state of a thread.
—And many more.
137

Logical errors:

These errors representthe errors in logic of the program. The programmer might be using wrong
formula or the design of the program itself is wrong. Logical errors are not detected by either by
java compiler or JVM. By comparing the output of a program with manually calculated results, a
programmer can guess the presence of a logical error.

Exception Handling
An exception is a condition that is caused by a run-time error in the program. When the java
interpreter encounters an error such as dividing an integer by zero, it creates an exception object
and throws it (informs us that an error occurs).

If the exception object is not caught and handled properly, the interpreter will display an error
message as shown in the above output and will terminate the program.

If we want the program to continue with the execution of the remaining code, then we should try
to catch the object thrown by the error condition and then display an appropriate message for
taking corrective actions. This task is known as Exception Handing.
The following table shows the some common errors that are occurred in the java programs.
Exception Type Cause of Exception
ArithemeticException Caused by the math errors
such as division by zero.
ArrayIndexOutOfBoundsException Caused by bad array indexes.
FileNotFoundException Caused by an attempt to
access a non existing file.
NumberFormatException Caused when a conversion
between strings and numbers
fails.
NullPointerException Caused by referencing a null
object.

Exceptions in java can be categorized into two types.


 Checked Exceptions:
These exceptions are explicitly handled in the code itself with the help of try-catch
blocks. Checked exceptions are extended from the java.lang.Exception class.
 Unchecked Exceptions:
These exceptions are not essentially handled in the program code, instead the JVM
handles such exceptions. Unchecked exceptions are extended from the class
java.lang.RuntimeException.
Syntax of Exception Handling Code
The basic concepts of exception handling are throwing an exception and catching it.
This illustrates in the following figure.
138

Java uses the keywords try and catch to handles the exceptions in the java programs.

try block:
The statements that produces exception are identified in the program and the
statements are placed in try block.
Syntax:
try
{
//Statements that causes Exception
}

catch block:
The catch block is used to process the exception raised. The catch block is placed
immediately after the try block.
Syntax:
catch(ExceptionType ex_ob)
{
//Statements that handle Exception
}
The following program illustrates the use of using the try and catch blocks in the java
programs.

class Error3
{
public static void main(String args[])
{
int a=10;
int b=5;
int c=5;
int x,y;
try
{
x=a/(b-c); //Division by zero
System.out.println("x=" + x);
}
catch(ArithmeticException e)
139

{
System.out.println("Division by Zero error occured");
}
y=a/(b+c);
System.out.println("y=" + y);
}
}
Output

Note that the program did not stop at the point of exception condition. It catches
the error condition, prints the error message.

--xxx—

Types of Exceptions
All exception types are subclasses of the built-in class Throwable. 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. The other branch is topped by Error, which defines exceptions that are
not expected to be caught under normal circumstances by your program.

Exceptions in java can be categorized into two types.


140

 Checked Exceptions:
These exceptions are explicitly handled in the code itself with the help of try-catch
blocks. Checked exceptions are extended from the java.lang.Exception class.
 Unchecked Exceptions:
These exceptions are not essentially handled in the program code, instead the JVM
handles such exceptions. Unchecked exceptions are extended from the class
java.lang.RuntimeException.

List out some common predefined exceptions?

Sno Exception name Meaning


Caused by math errors such as division by
1 ArithmeticException
zero
Caused due to accessing the array indices
2 ArrayIndexOutOfBoundsException
which out of range
Caused due to assignment to an array
3 ArrayStoreException
element of an incompatible type.
Caused when a conversion between string
4 NumberFormatException
and fails
5 NullPointerException Caused when referring a null object
6 ClassCastException Caused when invalid casting of an object
Caused when trying to create an array with
7 NegetiveArraySizeException
negative size
8 NoSuchFieldException Caused when requested field does not exist

9 NoSuchMethodException Cased when requested method does not exist

Caused when the system runs out of stack


10 StackOverFlowException
space

--xxx—

Multiple catch Clauses with an example


141

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. When an exception is thrown, each catch statement is inspected in order, and the first
one whose type matches that of the exception is executed.

When you use multiple catch statements, 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. Further, in Java, unreachable code is an error.
Example:
classMultiCatch {
public static void main(String args[ ]) {
try {
int a = args.length;
System.out.println("a = " + a);
int b = 42 / a;
int c[ ] = { 1 };
c[42] = 99;
}

catch(ArithmeticException e) {
System.out.println("Divide by 0: " + e);
}

catch(ArrayIndexOutOfBoundsException e) {
System.out.println("Array index oob: " + e);
}

catch(Exception e){
System.out.println(e.getMessage());
}
System.out.println("After try/catch blocks.");
}
}

throw Statement
It is possible for your program to throw an exception explicitly, using the throw statement. The
general form of throw is

throwThrowableInstanc
e;
The flow of execution stops immediately after the throw statement; any subsequent statements
are not executed. The nearest enclosing try block is inspected to see if it has a catch statement
that matches the type of the exception. If it does find a match, control is transferred to that
statement.

throws statement
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. You 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. This is necessary for all exceptions, except those of type
142

Error or RuntimeException, or any of their subclasses. All other exceptions that a method can
throw must be declared in the throws clause. If they are not, a compile-time error will result.
Syntax:

type method-name(parameter-list) throws exception-list

// body of method

Example:
classthr{
static void demo( ) throws ArithmeticException
{
System.out.print("inside demo");
throw new ArithmeticException("division error");
}
public static void main(String args[ ]){
try{
demo();
}
catch(Exception e){
System.out.print(e.getMessage());
}
}
}

finally 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 theexception.Any time a method is
about to return to the caller from inside a try/catch block, via an uncaught exception or an explicit
return statement, the finally clause is also executed just before the method returns. The finally
clause is optional. However, each try statement requires at least one catch or a finally clause.
Example:
classFinallyDemo {
// Through an exception out of the method.
static void procA( )
{
try {
System.out.println("inside procA");
throw new RuntimeException("demo");
}
finally {
System.out.println("procA's finally");
}
143

}
// Return from within a try block.
static void procB( ) {
try {
System.out.println("inside procB");
return;
}
finally {
System.out.println("procB's finally");
}
}
// Execute a try block normally.
static void procC( ) {
try {
System.out.println("inside procC");
}
finally {
System.out.println("procC's finally");
}
}
public static void main(String args[]) {
try {
procA( );
}
catch (Exception e) {
System.out.println("Exception caught");
}
procB( );
procC( );
}
}
--xxx--

Creating Your Own Exception Subclasses


This is quite easy to do: just define a subclass of Exception (which is, of course, a subclass of
Throwable). Your subclasses don’t need to actually implement anything—it is their existence in the
type system that allows you to use them as exceptions.
The Exception class does not define any methods of its own. It does, of course, inherit those
methods provided by Throwable. Thus, all exceptions, including those that you create, have the
methods defined by Throwable available to them.
Example:
import java.io.*;
classEvenException extends Exception
{
EvenException( )
{
super("Given Number Is Even");
}
}
144

classOddException extends Exception


{
OddException(String st)
{
super(st);
}
}

classMY_Exception
{
public static void main(String args[ ])
{
DataInputStream in=new DataInputStream(System.in);
int n;
try{
System.out.println("Enter Any Integer Number");
n=Integer.parseInt(in.readLine( ));
if(n%2 ==0)
throw new EvenException( );
else
throw new OddException("Given Number Is Odd Number");
}
catch(EvenException e)
{
System.out.println(e.getMessage( ));
}
catch(OddException e)
{
System.out.println(e.getMessage( ));
}
catch(IOException e)
{
System.out.println(e.getMessage( ));
}
}
}

--xxx--

Potrebbero piacerti anche