[go: up one dir, main page]

0% found this document useful (0 votes)
26 views47 pages

Unit Iii

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
26 views47 pages

Unit Iii

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 47

III UNIT

Exceptions in Java

Exception Hierarchy

All exception and error types are subclasses of class Throwable, which is the 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:

There are mainly two types of exceptions:

Ø checked Exceptions

Ø unchecked Exception

Ø Checked Exception:
The classes which are directly inherited from Throwable class ,which are checked at
Compilation Process are known as checked exceptions.
Checked exceptions are checked at compile-time.
for e.g. IOException, SQLException etc.

Ø Unchecked Exception
· The classes which inherit from Throwable classes ,which occur 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
for e.g. ArithmeticException, NullPointerException, ArrayIndexOutOfBoundsException etc.
Ø The java.lang package defines several classes and exceptions.

Some of these classes are unchecked while some other classes are checked.

EXCEPTIONS DESCRIPTION CHECK UNCHECKED


ED

ArithmeticException Arithmetic errors such as a divide by - YES


zero

ArrayIndexOutOfBoundsEx Arrays index is not within array.length - YES


ception

ClassNotFoundException Related Class not found YES -

IOException InputOuput field not found YES -

IllegalArgumentException Illegal argument when calling a method - YES

InterruptedException One thread has been interrupted by YES -


another thread

NoSuchMethodException Nonexistent method YES -

NullPointerException Invalid use of null reference - YES

NumberFormatException Invalid string for conversion to number - YES

Exception Handling

Exception handling is a framework that is used to handle runtime errors only, compile time
errors are not handled by exception handling in java.

We use specific keywords in the java program to create an exception handler block.
Exception Handling Keywords

Java exception handling is managed via five keywords: try, catch, throw, throws, and finally.

Exception Keyword Description

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 a 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 occur an exception
in the method. It is always used with method signatures.

Termination or Resumptive models

Ø When an Exception is thrown , Control is transferred to the catch block that handles the error.

Ø The Programmer now has two Choices, that he can print the error message and exit from the
program.this technique is called as Termination Model.

Ø The user can also continue Execution by calling some other function after printing the error
message. This Technique is called the Resumptive Model.
If Exception handling is not Provided , then in a Java application the program stops
automatically after printing the exception message in try-catch block and also continues the code
after exception occurs by using try-catch block.

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 (ArthematicException e)

System.out.println(“divide by Zero”);

System.out.println(“After try Catch Block”);

}
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.

Here is the exception generated when the above example is executed:

Output:

java.lang.ArithmeticException: / by zero

at Exc0.main(Exc0.java:4)

The stack trace will always show the sequence of method invocations that led up to the error.
Using try and catch

· Although the default exception handler provided by the Java run-time system is useful for
debugging, you will usually want to handle an exception yourself.

· Doing so provides two benefits.

· First, it allows you to fix the error. Second, it prevents the program from automatically
terminating.

· 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 ArithmeticExceptiongenerated 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 the 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.

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 been executed, program control continues with the next line in the
program following the entire try/catch mechanism.

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, 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. After one catch statement executes, the others are
bypassed, and execution continues after the try/catch block.

The following example traps two different exception types:

// Demonstrate multiple catch statements.

class MultiCatch {

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);

System.out.println("After try/catch blocks.");

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].

Here is the output generated by running it both ways:

C:\>java MultiCatch

a=0

Divide by 0: java.lang.ArithmeticException: / by zero

After try/catch blocks.


C:\>java MultiCatchTestArg

a=1

Array index oob: java.lang.ArrayIndexOutOfBoundsException:42

After try/catch blocks.

Example2:

/* This program contains an error. A subclass must come before its superclass in a series of catch
statements. If not, unreachable code will be created and a

compile-time error will result.

*/

class SuperSubCatch {

public static void main(String args[]) {

try {

int a = 0;

int b = 42 / a;

} catch(Exception e) {

System.out.println("Generic Exception catch.");

/* This catch is never reached because ArithmeticException is a subclass of Exception. */

catch(ArithmeticException e) { // ERROR - unreachable

System.out.println("This is never reached.");

}
}

If you try to compile this program, you will receive an error message stating that the
second catch statement is unreachable because the exception has already been caught. Since
ArithmeticExceptionis 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.

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:

// An example of nested try statements.

class NestTry {

public static void main(String args[]) {

try {

int a = args.length;

/* If no command-line args are present,the following statement will generate a


divide-by-zero exception. */

int b = 42 / a;
System.out.println("a = " + a);

try { // nested try block

/* If one command-line arg is used, then a divide-by-zero exception will be generated by the
following code. */

if(a==1) a = a/(a-a); // division by zero

/* If two command-line args are used,then generate an out-of-bounds exception. */

if(a==2) {

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.
When you execute the program with no command-line arguments, a divide-by-zero
exception is generated by the outer try block.

Execution of the program with one command-line argument generates a divide-by-zero


exception from within the nested try block. Since the inner block does not catch this exception, it
is passed on to the outer try block, where it is handled.

If you execute the program with two command-line arguments, an array boundary
exception is generated from within the inner try block.

Here are sample runs that illustrate each case:

C:\>java NestTry

Divide by 0: java.lang.ArithmeticException: / by zero

C:\>java NestTryOne

a=1

Divide by 0: java.lang.ArithmeticException: / by zero

C:\>java NestTryOne Two

a=2

Array index out-of-bounds:

java.lang.ArrayIndexOutOfBoundsException:42

Example2 (Same as above calling by method in main Method):

/* Try statements can be implicitly nested via

calls to methods. */

class MethNestTry {

static void nesttry(int a) {

try { // nested try block


/* If one command-line arg is used, then a divide-by-zero exception will be generated by the
following code. */

if(a==1) a = a/(a-a); // division by zero

/* If two command-line args are used,then generate an out-of-bounds exception. */

if(a==2) {

int c[] = { 1 };

c[42] = 99; // generate an out-of-bounds exception

} catch(ArrayIndexOutOfBoundsException e) {

System.out.println("Array index out-of-bounds: " + e);

public static void main(String args[]) {

try {

int a = args.length;

/* If no command-line args are present,

the following statement will generate

a divide-by-zero exception. */

int b = 42 / a;

System.out.println("a = " + a);


nesttry(a);

} catch(ArithmeticException e) {

System.out.println("Divide by 0: " + e);

}}

Using Throw:

Ø The throw keyword in Java is used to explicitly throw an exception from a method or
any block of code. We can throw either checked or unchecked exceptions.

Ø The throw keyword is mainly used to throw custom exceptions.

Syntax:

throw new ThrowableInstance(parameter);

Here, ThrowableInstancemust be an object of type Throwableor a subclass of Throwable.

Forexample:

Exception is a sub-class of Throwable and user defined exceptions typically extend Exception
class.

example:

class MyException extends Exception {

public MyException(String msg){

//super(msg);

System.out.println(msg);

}
public class MyTest {

static int divide(intfirst,int second) throws MyException{

if(second==0){

throw new MyException("can't be divided by zero");

return first/second;

public static void main(String[] args)throws MyTest

System.out.println(divide(4,0));

Output of program:

C:\Roseindia\vinod\Exception>javac Test.java

C:\Roseindia\vinod\Exception>java Test
MyException: can't be divided by zero
at Test.divide(Test.java:10)
at Test.main(Test.java:15)

Using throws:

The Java throws keyword is used to declare an exception. It gives 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 the programmer's 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:

import java.io.*;

class Test3{
public static void main(String args[]) throws FileNotFoundException,IOException

{
FileInputStreamfis=null;
fis = new FileInputStream (new File (args[0]));
intch;
while ((ch = fis.read()) != -1){
System.out.print ((char) ch);
}
fis.close();
}
}

output:

C:\Roseindia\vinod\Exception>javac Test3.java

C:\Roseindia\vinod\Exception>java Test3
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at Test3.main(Test3.java:6)

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.

Example1 Example2
class TestFinallyBlock{
public static void main(String args[]){ import java.io.*;
try
{ class Test{
int data=25/0; public static void main(String args[]){
System.out.println(data); FileInputStreamfis=null;
} try {
catch(ArithmeticException e) fis = new FileInputStream (new File
{ System.out.println(e); } (args[0]));
intch;
finally while ((ch = fis.read()) != -1){
{ System.out.println("finally block is System.out.print ((char) ch);
always executed"); } }
}
System.out.println("rest of the code..."); catch (FileNotFoundException e){
} System.out.println("File not found!");
} }
Output: catch (IOException e){
java.lang.ArithmeticException: / by System.out.println("Unable to read file!");
zero }
finally block is always executed
rest of the code...
finally{
System.out.println();
System.out.println("In finally.");
try{
if(fis!=null){
fis.close();
}
}
catch (IOExceptionioe){
System.out.println("In finally.");
}
}

}
}

Output:
C:\Roseindia\vinod\Exception>javac Test.java

C:\Roseindia\vinod\Exception>java Test abc


File not found!
In finally.

Java’s Built-in Exceptions

Inside the standard package java.lang, Java defines several exception classes.

The most general of these exceptions are subclasses of the standard type RuntimeException.

These exceptions need not be included in any method’s throws list.

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.

those 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.

Java defines several other types of exceptions that relate to its various class libraries.

Java’s Unchecked RuntimeExceptionSubclasses Defined in java.lang

Java’s Checked Exceptions Defined in java.lang

Creating own exception subclasses.

If you are creating your own Exception that is known as a custom exception or user-defined
exception. Java custom exceptions are used to customize the exception according to user need.

package mypack;

class InvalidAgeException extends Exception{


String ss;

InvalidAgeException(String s){

super(s);

System.out.println("not valid");

Import mypack. InvalidAgeException;

import java.io.*;

class TestCustomException1{

static void validate(int age)throws InvalidAgeException{

if(age<18)

throw new InvalidAgeException("not valid for vote");

else

System.out.println("welcome to vote");

public static void main(String args[]){

try{

validate(13);

catch(Exception m)

System.out.println("Exception occured: "+m);


m.printStackTrace();

System.out.println("rest of the code...");

} }

Output:

not valid

mypack.InvalidAgeException: not valid for vote

Exception occured: mypack.InvalidAgeException: not valid for vote

at excetions.myex.validate(myex.java:26)

at excetions.myex.main(myex.java:32)

Threads

What Is a Thread?

A thread is a single sequential flow of control within a program.

A single thread also has a beginning, an end, a sequence, and at any given time during the
runtime of the thread there is a single point of execution. However, a thread itself is not a
program. It cannot run on its own, but runs within a program.

A thread is considered lightweight because it runs within the context of a full-blown program
and takes advantage of the resources allocated for that program and the program's environment.

Multitasking programming is of two types –

1. Process-based Multitasking
A process is an instance of a computer program that is executed sequentially. It is a
collection of instructions which are executed simultaneously at the rum time. Thus
several processes may be associated with the same program.

Example :– We can listen to music and browse the internet at the same time. The
processes in this example are the music player and browser.

2. Thread-based Multitasking.

A thread is a lightweight process which exists within a program and is executed to perform a
special task. Several threads of execution may be associated with a single process. Thus a
process that has only one thread is referred to as a single-threaded process, while a process with
multiple threads is referred to as a multi-threaded process.

Example: – Using a browser we can navigate through the webpage and at the same time
download a file. In this example, navigation is one thread and downloading is another
thread. Also in a word-processing application like MS Word, we can type text in one
thread and spell checker checks for mistakes in another thread.

Differences between thread-based multitasking and process-based Multitasking.

Thread Based Multi-tasking Process Based Multi-tasking

Thread is a such part of multithreaded A process is essence of program that is executing


program which which running parallel

defines separate path for execution

It doesn’t support java compiler It allows you to run java compiler

and the text editor runs simultaneously. and a text editor at the same time.

Both have performed different

tasks.
Thread multitasking has less Process multitasking has more overhead than thread
multitasking.
overhead than process multitasking.

It allows taking gain access over Here, it is unable to gain access

idle time taken by CPU. over idle time of the CPU.

It is totally under control of java. It is not under control of java.

Thread based multitasking is Process based multitasking is a comparatively


heavyweight process compared to thread based
known to be a lighter weight process. multitasking.

Inter-thread communication is Inter-process communication is

inexpensive and context switching from expensive and limited


one thread to another.

It has faster data rate multithreading or It has slower data rate multitasking.
tasking

Threads share the same address space. Process requires its own address space.

Thread is a smaller unit Program is a bigger unit.

In thread based multitasking two or In process based multitasking two or more


more threads can be run concurrently. processes and programs can be run concurrently.

Java thread model


Java uses threads to enable the entire environment to be asynchronous (occurring at same time).
This helps reduce inefficiency by preventing the waste of CPU cycles.

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.

Multithreading allows animation loops to sleep for a second between each frame without
causing the whole system to pause. When a thread blocks in a Java program, only the single
thread that is blocked pauses. All other threads continue to run.

Threads exist in several states

1. A thread can be running. It can be ready to run as soon as it gets CPU time.

2. A running thread can be suspended, which temporarily suspends its activity.

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

4. A thread can be blocked when waiting for a resource.

5. At any time, a thread can be terminated, which halts its execution immediately. Once
terminated, a thread cannot be resumed.

Life Cycle of Thread

A thread can be in one of the five states. According to Sun, there are 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
● Runnable
● Running
● Non-Runnable (Blocked)
● Terminated

Following are the stages of the life cycle −

● New − A new thread begins its life cycle in the new state. It remains in this state until the
program starts the thread. It is also referred to as a born thread.
● Runnable − After a newly born thread is started, the thread becomes runnable. A thread
in this state is considered to be executing its task.

● Waiting − Sometimes, a thread transitions to the waiting state while the thread waits for
another thread to perform a task. A thread transitions back to the runnable state only
when another thread signals the waiting thread to continue executing.

● Timed Waiting (sleep) − A runnable thread can enter the timed waiting state for a
specified interval of time. A thread in this state transitions back to the runnable state
when that time interval expires or when the event it is waiting for occurs.

● Terminated (Dead) − A runnable thread enters the terminated state when it completes its
task or otherwise terminates.

Creating threads:

In Java, an object of the Thread class can represent a thread. Thread can be implemented through
any one of two ways:

● Extending the java.lang.Thread Class


● Implementing the java.lang.Runnable Interface

There are two ways to create a thread:

1. By extending Thread class


2. By implementing Runnable interface.

1.Thread class:

Thread class provides 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 a 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 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:
publicclassMyClassextendsThread {
public void run(){
System.out.println("MyClass running");
}
}
To create and start the above thread you can do so like this:
MyClasst1=newMyClass ();
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.

Methods of Thread class:


1. public void run():
This method is used to perform needed actions for a thread. This method is called by JVM after
the start() method is called.
2. public void start():
This method is called by the thread object to start the execution of the thread. After this method
is called, JVM automatically calls the run() method.
3. public void sleep(long milliseconds):
This method ceases the execution of the currently executing thread for the time period
specified.
4. public void join():
This method causes the current thread (which calls this method) to wait until another thread
dies.
5. public void join(long milliseconds):
This method causes the current thread (which calls this method) to wait for a thread to die for
the specified milliseconds.
6. public intgetPriority():
This method returns the priority (integer value) of the thread.
7. public intsetPriority(int priority):
This method sets the priority of the thread. The priority is in terms of integer values from 1 to 10.
Priority increases with an integer value from 1 being the lowest and 10 being the highest.
8. public String getName():
This method returns the name of the calling thread.
9. public void setName(String name):
This method changes the name of the calling thread.
10. public Thread currentThread():
This method returns the reference of the current thread which is executing.
11. public intgetId():
This method returns the ID of the calling thread.
12. public Thread.StategetState():
This method returns the state of the calling thread.
13. public booleanisAlive():
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 a 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 Daemon():
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 a daemon or user thread.
20. public void interrupt():
This method interrupts the running thread.
21. public booleanisInterrupted():
This method returns true if the thread has been interrupted, else returns false.
22. public static boolean interrupted():
This method returns true if the current thread has been interrupted, else returns false.

Java Thread Example by extending Thread class


class Multi extends Thread{
public void run(){
System.out.println("thread is running...");
}
public static void main(String args[]){
Multi t1=new Multi();
t1.start();
}
}

Output: thread is running...

Example: 2

class MyThread extends Thread


{
String s=null;
MyThread(String s1)
{
s=s1;
start();
}
public void run()
{
System.out.println(s);
}
}
public class RunThread
{
public static void main(String args[])
{
MyThread m1=new MyThread("Thread started....");
}
}
Output:
Thread started....

Creation of Multiple Threads

class Mythread extends Thread{


Mythread(String s){
super(s);
start();
}
public void run(){
for(inti=0;i<5;i++){
System.out.println("Thread Name :"
+Thread.currentThread().getName());
try{
Thread.sleep(1000);
}catch(Exception e){}
}
}
}
public class threadmult{
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 interfaces have only one method named run().

public void run(): is used to perform an action for a thread.


The easiest way to create a thread is to create a class that implements the Runnable interface.

To implement a Runnable interface, a class need only implement a single method called run( ),
which is declared like this:

public void run( )

Inside run( ), we will define the code that constitutes the new thread.
Example:

publicclassMyClassimplementsRunnable {
public void run(){
System.out.println("MyClass running");
}
}

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:

Threadt1=newThread(newMyClass ());
t1.start();

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 ".

Java Thread Example by implementing Runnable interface

class Multi3 implements Runnable{


public void run(){
System.out.println("thread is running...");
}

public static void main(String args[]){


Multi3 m1=new Multi3();
Thread t1 =new Thread(m1);
t1.start();
}
}
Output: thread is running...

Example2:

class MyThread1 implements Runnable{


Thread t;
String s=null;
MyThread1(String s1) {
s=s1;
t=new Thread(this);
t.start();

}
public void run() {
System.out.println(s);

}
}

public class RunableThread{


public static void main(String args[]) {

MyThread1 m1=new MyThread1("Thread started....");

}
}
Output: Thread started....

Creation of Multiple Threads

class MyThread1 implements Runnable{


Thread t;
MyThread1(String s) {
t=new Thread(this,s);

/*Thread(Runnable r, String name)This constructor creates a thread object having two


arguments of String and Runnable type.*/

t.start();
}

public void run() {


for(inti=0;i<5;i++) {
System.out.println("Thread Name :"+Thread.currentThread().getName());
try {
Thread.sleep(1000);
}catch(Exception e){}
}
}
}

public class threadmultirunnable{


public static void main(String args[]) {
System.out.println("Thread Name :"+Thread.currentThread().getName());
MyThread1 m1=new MyThread1("My Thread 1");
MyThread1 m2=new MyThread1("My Thread 2");
}
}
Output:
Thread Name :main

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

Thread Name :My Thread 2

Thread Name :My Thread 1

Thread Name :My Thread 2

Thread Name :My Thread 1

Using sleep():

class TestSleepMethod1 extends Thread{


public void run()
{
for(inti=1;i<5;i++)
{
try{
Thread.sleep(500);
}
catch(InterruptedException e)
{
System.out.println(e);
}

System.out.println(i);
}
}

public static void main(String args[]){


TestSleepMethod1 t1=new TestSleepMethod1();
TestSleepMethod1 t2=new TestSleepMethod1();

t1.start();
t2.start();
}
}

Output:
1
1
2
2
3
3
4
4

Thread priority in Java:


A thread is a part or entity of a process that is scheduled for execution.

As we know Java is a multithreading language which means JVM allows an application to have
multiple threads running concurrently. In Java each and every thread has priority, priority means
which decides the order of execution of that thread. Thread with higher priority will run first with
thread with lower priority and thread with equal priority will be treated the same by the scheduler
and they will follow the FCFS(First Cum First Serve) algorithm. We can also set the priority of
the thread by using setPriority() method as follows:

ThreadNamesetPriority(int number);

Here the number is an integer value between 1 to 10, here 1 is a minimum priority and 10 is the
maximum priority.
Thread class defines some priority constants as follows:
MIN_PRIORITY = 1
NORM_PRIORITY = 5
MAX_PRIORITY = 10;
In any thread, NORM_PRIORITY is the default one.
In Java, each and every thread has a priority which is defined by a number between, 1 to 10,
with 1 being the lowest priority,
10 being the highest priority,
A default priority for a thread is 5 but you can even set the priority for a thread.

Example:

class A extends Thread


{
public void run()
{
System.out.println("Thread A strated");
for(inti=0;i<=5;i++)
{
System.out.println("For thread A = "+i);
}
System.out.println("Exit from Thread A");
}

class B extends Thread


{
public void run()
{
System.out.println("Thread B strated");
for(inti=0;i<=5;i++)
{
System.out.println("For thread B = "+i);
}
System.out.println("Exit from Thread B");
}

public class threadpriority


{
public static void main(String args[])
{
A th1=new A();
B th2=new B();
th1.setPriority(Thread.NORM_PRIORITY); //largest value be the first
th2.setPriority(th1.getPriority()-1); //lowest value be the second
System.out.println("Start thread A main");
th1.start();

System.out.println("Start Thread B main");


th2.start();
System.out.println("End of Main Thread main ");
}
}
Output:
Start thread A main
Start Thread B main
End of Main Thread main
Thread A started
For thread A = 0
For thread A = 1
For thread A = 2
For thread A = 3
For thread A = 4
For thread A = 5
Exit from Thread A
Thread B started
For thread B = 0
For thread B = 1
For thread B = 2
For thread B = 3
For thread B = 4
For thread B = 5
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 results due to
concurrency issues. For example, if multiple threads try to write within the same file then they
may corrupt the data because one of the threads can override data, or while one line 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.

The key to synchronization is the concept of the monitor (also called a semaphore). A monitor is
an object used as a mutually exclusive lock, or mutex. Only one thread can own a monitor at a
given time. When a thread acquires a lock, it is said to have entered the 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 object identifier is a reference to an object whose lock is associated with the monitor
that the synchronized statement represents.
Java Synchronization is a better option where we want to allow only one thread to access the
shared resource.
The synchronization is mainly used to
To prevent thread interference.
To prevent consistency problems.
Mutual Exclusive
Mutual Exclusive helps keep threads from interfering with one another while sharing data. This
can be done in three ways in Java:
1. by
2. By synchronized block
3. By static synchronization
In this example, there is no synchronization, so the output is inconsistent. Let's see the
example:
class Table{
void printTable(int n){//method not synchronized
for(inti=1;i<=5;i++){
System.out.println(n*i);
try{
Thread.sleep(400);
}catch(Exception e){System.out.println(e);}
}

}
}

class MyThread1 extends Thread{


Table t;
MyThread1(Table t){
this.t=t;
}
public void run(){
t.printTable(5);
}

}
class MyThread2 extends Thread{
Table t;
MyThread2(Table t){
this.t=t;
}
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:


If you declare any method as synchronized, it is known as a synchronized method.
The synchronized method is used to lock an object for any shared resource.
When a thread invokes a synchronized method, it automatically acquires the lock for that
object and releases it when the thread completes its task.

Example of Java synchronized method


class Table{
synchronized void printTable(int n){//synchronized method
for(inti=1;i<=5;i++){
System.out.println(n*i);
try{
Thread.sleep(400);
}catch(Exception e){System.out.println(e);}
}

}
}

class MyThread1 extends Thread{


Table t;
MyThread1(Table t){
this.t=t;
}
public void run(){
t.printTable(5);
}

}
class MyThread2 extends Thread{
Table t;
MyThread2(Table t){
this.t=t;
}
public void run(){
t.printTable(100);
}
}

public class TestSynchronization2{


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
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 a synchronized block.
If you put all the codes of the method in the synchronized block, it will work the same as the
synchronized method.

class Table{
void printTable(int n){
synchronized(this){//synchronized block
for(inti=1;i<=5;i++){
System.out.println(n*i);
try{
Thread.sleep(400);
}catch(Exception e){System.out.println(e);}
}
}
}//end of the method
}
class MyThread1 extends Thread{
Table t;
MyThread1(Table t){
this.t=t;
}
public void run(){
t.printTable(5);
}
}
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

Example of static synchronization


In this example, we are applying a synchronized keyword on the static method to perform static
synchronization.
class Table{

synchronized static void printTable(int n){


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

class MyThread1 extends Thread{


public void run(){
Table.printTable(1);
}
}

class MyThread2 extends Thread{


public void run(){
Table.printTable(10);
}
}

class MyThread3 extends Thread{


public void run(){
Table.printTable(100);
}
}
class MyThread4 extends Thread{
public void run(){
Table.printTable(1000);
}
}

public class TestSynchronization4{


public static void main(String t[]){
MyThread1 t1=new MyThread1();
MyThread2 t2=new MyThread2();
MyThread3 t3=new MyThread3();
MyThread4 t4=new MyThread4();
t1.start();
t2.start();
t3.start();
t4.start();
}
}

Output:

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 the second thread is
waiting for an object lock that is acquired by the first thread. 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.
Inter-thread communication in Java

Cooperation (Inter-thread communication) is a mechanism in which a thread is paused running


in its critical section and another thread is allowed to enter (or lock) in the same critical section
to be executed.
multithreading replaces event loop programming by dividing your tasks into discrete, logical
units. Threads also provide a secondary benefit: they do away with polling. Polling is usually
implemented by a loop that checks some conditions repeatedly. Once the condition is true,
appropriate action is taken. This wastes CPU time.

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 waits 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.

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()
notify()
notifyAll()
wait() method
Causes the current thread to wait until another thread invokes the notify().
Method
Description
public final void wait()throws InterruptedException
waits until the object is notified.

public final void wait(long timeout)throws InterruptedException


waits for the specified amount of time.

public void notify()


Wakes up a single thread that is waiting on this object's monitor.
public void notifyAll()
Wakes up all the threads that are called wait( ) on the same object.

Difference between wait and sleep.

wait()
sleep()
wait() method releases the lock
sleep() method doesn't release the lock.
is the method of Object class
is the method of the Thread class
is the non-static method
is the static method
is the non-static method
is the static method
should be notified by notify() or notifyAll() methods
After the specified amount of time, sleep is completed.

Example :
class Customer{
int amount=10000;
synchronized void withdraw(int amount){
System.out.println("going to withdraw...");
if(this.amount<amount){
System.out.println("Less balance; waiting for deposit...");
try{wait();}catch(Exception e){}
}
this.amount-=amount;
System.out.println("withdraw completed...");
}
synchronized void deposit(int amount){
System.out.println("going to deposit...");
this.amount+=amount;
System.out.println("deposit completed... ");
notify();
}
}
class threadclass{
public static void main(String args[]){
final Customer c=new Customer();
new Thread(){
public void run(){c.withdraw(15000);}
}.start();
new Thread(){
public void run(){c.deposit(10000);}
}.start();

}}

output:
going to withdraw...
Less balance; waiting for a deposit...
going to deposit...
deposit completed...
withdraw completed..
Example2:
class Chat {
boolean flag = false;
public synchronized void Question(String msg) {
if (flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(msg);
flag = true;
notify();
}
public synchronized void Answer(String msg) {
if (!flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(msg);
flag = false;
notify();
}
}

class T1 implements Runnable {


Chat m;
String[] s1 = { "Hi", "How are you ?", "I am also doing fine!" };

public T1(Chat m1) {


this.m = m1;
new Thread(this, "Question").start();
}
public void run() {
for (inti = 0; i< s1.length; i++) {
m.Question(s1[i]);
}
}
}
class T2 implements Runnable {
Chat m;
String[] s2 = { "Hi", "I am good, what about you?", "Great!" };

public T2(Chat m2) {


this.m = m2;
new Thread(this, "Answer").start();
}
public void run() {
for (inti = 0; i< s2.length; i++) {
m.Answer(s2[i]);
}
}
}
public class chatThread {
public static void main(String[] args) {
Chat m = new Chat();
new T1(m);
new T2(m);
}
}
output:
Hi
Hi
How are you ?
I am good, what about you?
I am also doing fine!
Great!

Example3:
import java.io.*;
class Chat {
boolean flag = false;

public synchronized void Question(String msg) {


if (flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Question:"+msg);
flag = true;
notify();
}
public synchronized void Answer(String msg) {
if (!flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Answer:"+msg);
flag = false;
notify();
}
}
class T1 implements Runnable {
Chat m;
BufferedReaderbr=new BufferedReader(new InputStreamReader(System.in));
String s1=br.readLine();
String[] s11 = {s1};
public T1(Chat m1)throws Exception {
this.m = m1;
new Thread(this, "Question").start();
}

public void run() {


try{
// String s1=br.readLine();
for (inti = 0; i< s11.length; i++) {
m.Question(s11[i]);
}
}catch(Exception e)
{e.printStackTrace();}
}

class T2 implements Runnable {


Chat m;
BufferedReaderbr=new BufferedReader(new InputStreamReader(System.in));
String s2=br.readLine();
String[] s22 = {s2};
public T2(Chat m2)throws Exception {
this.m = m2;
new Thread(this, "Answer").start();
}
public void run() {
try{
//String s2=br.readLine();
for (inti = 0; i< s22.length; i++) {
m.Answer(s22[i]);
}
}catch(Exception e)
{e.printStackTrace();}
}
}
public class chatThread {
public static void main(String[] args)throws Exception {
Chat m = new Chat();
new T1(m);
new T2(m);
}
}

output:
hi
Question:hi
hello
Answer:hello

You might also like