Multi
Threading
Multithreading is a
programming concept where a program is divided into more than one sub programs
called processes, which can be executed in parallel at the same time. Multi
tasking feature of an operating system where more than one tasks can be
executed at the same time is actually multithreading.
A thread has a single flow of control: Thread has a beginning, body
(set of instructions to be executed), and an end. The instructions in the body
of the thread are executed sequentially. All main programs we have seen in
earlier examples can be called single
thread. Java supports multithreading, each thread is a small program which
has its own flow of control and runs in parallel of other threads (programs). Main
method of java program is actually main thread and it starts other threads. All
these threads shares computer resources (CPU RAM etc) jointly. These threads of
an main application are also called as lightweight
threads or lightweight processes.
Multithreading is a powerful concept of the java which allow programmers to do
multiple things together. Long programs can be broken into threads and executed
in parallel.
Creating
Threads
Thread contains run method which is heart of the
thread. Run method makes up entire body of the thread.
Example:
public void run()
{
------- // Body of
thread
}
A thread can be created by two methods.
1. By
creating a thread class: Define a class that extends thread class, override run()
method of thread class in new created
class and add code in run() method required by the thread.
2. By
converting a class to a thread: Define a class that implements Runnable interface. Runnable interface
has only one method run().
Extending
Thread class
We can make our thread class by extending the class java.lang.Thread. To create and execute
a thread using class Thread we will need to do following:
1. Declare
a class that extends Thread class.
2. Implement run()
method which contains code of thread.
3. Create
object of thread and call start()
method.
Example:
There
are three classes in this example MyClassOne,
MyClassTwo, MyClassThree extends Thread class. In all the
three classes method run() has
implemented which displays a message. In main()
method object of all the three classes has created objectOne, objectTwo, objectThree. To start threads start function is called objectOne.start(), objectTwo.start(),
objectThree.start().
class MyClassOne extends Thread
{
public void run()
{
System.out.println("My Class One");
}
}
class MyClassTwo extends Thread
{
public void run()
{
System.out.println("My Class Two");
}
}
class MyClassThree extends Thread
{
public void run()
{
System.out.println("My Class Three");
}
}
public class ThreadExample
{
public static void main(String arg[]){
MyClassOne objectOne = new MyClassOne();
MyClassTwo objectTwo = new MyClassTwo();
MyClassThree objectThree = new MyClassThree();
objectOne.start();
objectTwo.start();
objectThree.start();
}
}
The output of this program is:
My Class Two
My Class One
My
Class Three
Note that we called start() function of class one
first then of class two and finally class three but if we see result the class
two thread was executed first then first then third. Means all three threads
executed independently so they displayed result when they executed not in
sequence they called.
Stopping
a Thread
Some time situation occurs when we want to stop a
thread from further execution, we stop a thread from execution by calling a
method stop().
Example:
objectOne.stop();
This statement will stop the execution
of thread permanently. It will force thread to move to dead state. Thread also move to the dead state when complete body
is executed and it reaches to the end.
Blocking
or Pausing a Thread
Thread can be temporarily blocked (paused) from
execution when needed. Following three
methods can be used to block (pause) a thread from execution.
1. sleep():
Blocks execution of a thread for specified time.
2. suspend():
Blocks thread from execution until further order. A method resume() is used to restart execution of a suspended thread.
3. wait():
Block Blocks execution of a thread until certain condition occurs. A method notify() is called to restart for a
thread in wait state.
These methods
can be used to force a thread to go into blocked
state. Any of these methods can be called to block a thread from execution as
per requirement.
Life
Cycle of a Thread
Life cycle of a thread contains following states:
1. Newborn
State
2. Runnable
State
3. Running
State
4. Blocked
(Paused) State
5. Dead
State
Newborn
State
Creation of an object of a thread is called newborn thread. In this state thread is
created but not started, we can perform two operations start() and stop() on
the thread in newborn state. The method start()
schedule a thread for running and stop()
kills the thread (force it to go into dead state).
Runnable
State
Thread which is ready
for execution and waiting for availability of the processor is called runnable
state of the thread. In this state thread is in the queue of the threads
waiting for processor. When we want a thread to release its control and shift
control to equal prority thread whose turn has not yet come we use yield() method.
Running
State
The thread which is
being executed (using CPU) currently is called in running state. A thread runs
until it completes execution of all the statements in the body of thread or it
is interrupted by the high priority threads. A thread can be interrupted by
using following methods sleep(), suspend() or wait().
Blocked
State
A thread which is
prevented from entering into runnable state and subsequently into running state
is called in blocked state. This happens when thread is suspended,
waiting or sleeping due to some reason. Blocked thread is not dead, it can be
considered as “not runnable”.
Dead
State
Life of a running threads ends when run() method of the thread completes
its execution. We can also use stop()
method to force a thread to go into dead state. A thread can be killed when it
is in newborn state, blocked state or running state.
Example:
class MyClassOne extends Thread
{
public void run()
{
for(int i=0; i<=5; i++)
{
if(i==2) yield();
System.out.println("Counter of Class one: =" + i);
}
System.out.println("Exit from My Class One !");
}
}
class MyClassTwo extends Thread
{
public void run()
{
for(int i=0; i<=5; i++)
{
System.out.println("Counter of Class Two: =" + i);
if(i==3) stop();
}
System.out.println("Exit from My Class Two !");
}
}
class MyClassThree extends Thread
{
public void run()
{
for(int i=0; i<=5; i++)
{
System.out.println("Counter of Class Three: =" + i);
if(i==2)
try {
sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("Exit from My Class Three !");
}
}
public class ThreadExample
{
public static void main(String arg[]){
MyClassOne objectOne = new MyClassOne();
MyClassTwo objectTwo = new MyClassTwo();
MyClassThree objectThree = new MyClassThree();
System.out.println("Start thread one");
objectOne.start();
System.out.println("Start thread two");
objectTwo.start();
System.out.println("Start thread three");
objectThree.start();
System.out.println("Main thread END");
}
}
Output of this program is:
Start
thread one
Start
thread two
Start
thread three
Main
thread END
Counter
of Class Two: =0
Counter
of Class Two: =1
Counter
of Class Two: =2
Counter
of Class Two: =3
Counter
of Class one: =0
Counter
of Class one: =1
Counter
of Class Three: =0
Counter
of Class Three: =1
Counter
of Class Three: =2
Counter
of Class one: =2
Counter
of Class one: =3
Counter
of Class one: =4
Counter
of Class one: =5
Exit
from My Class One !
Counter
of Class Three: =3
Counter
of Class Three: =4
Counter
of Class Three: =5
Exit
from My Class Three !
Every
time you execute this program it will give slightly different sequence of
output. But the effect of methods yield(), stop() and sleep() will be same. In
first thread we have used yield()
method on condition if(i==2) yield(). So when value of I becomes 2, the control is
shifted to next thread. We have used method stop() in second thread on condition if(i==3) stop() so when
value of I reaches 3, execution of this thread stopped and no further statement
in this thread is executed. Similarly we have used sleep() in thread three if(i==2)… sleep(1000). When
value of i becomes 2 then execution of thread blocked for 1000 milliseconds. We will learn
exception handling (try… catch) in next
chapter.
Priority
of Threads
Each thread in java has
priority, on the basis of that threads are executed. Threads we created in
previous example have same priority. Equal priority threads are executed on
first come first serve basis. Java allows us to set the priority of threads
using setPriority() method. The Thread
class has some predefined priorities as given below.
MIN_PRIORITY
= 1
NORM_PRIORITY
= 5
MAX_PRIORITY
= 10
Example:
MyThread.setPriority(integer)
Parameter passed to the
method setPriority() is an integer
number between 1 to 10. Execution of threads will be on the basis of their
priority. If there are many threads in the queue for execution then highest priority
thread will be executed first and lowest priority thread will be executed in
the last. If a new thread with higher priority comes in and a thread of lower
priority is already executing then execution of already executing thread will
be blocked and execution of new higher priority thread will start.
Example:
class MyClassOne extends Thread
{
public void run()
{
System.out.println("Beginning of thread My Class One !");
for(int i=0; i<=5; i++)
{
System.out.println("Counter of Class one: =" + i);
}
System.out.println("Exit from My Class One !");
}
}
class MyClassTwo extends Thread
{
public void run()
{
System.out.println("Beginning of thread MyClassTwo !");
for(int i=0; i<=5; i++)
{
System.out.println("Counter of Class Two: =" + i);
}
System.out.println("Exit from My Class Two !");
}
}
class MyClassThree extends Thread
{
public void run()
{
System.out.println("Beginning of thread MyClassThree !");
for(int i=0; i<=5; i++)
{
System.out.println("Counter of Class Three: =" + i);
}
System.out.println("Exit from My Class Three !");
}
}
public class ThreadExample
{
public static void main(String arg[]){
MyClassOne objectOne = new MyClassOne();
MyClassTwo objectTwo = new MyClassTwo();
MyClassThree objectThree = new MyClassThree();
objectThree.setPriority(Thread.MAX_PRIORITY);
objectTwo.setPriority(Thread.NORM_PRIORITY);
objectOne.setPriority(Thread.MIN_PRIORITY);
System.out.println("Start thread one");
objectOne.start();
System.out.println("Start thread two");
objectTwo.start();
System.out.println("Start thread three");
objectThree.start();
System.out.println("Main thread END");
}
}
The output of this
program is:
Start
thread one
Start
thread two
Start
thread three
Main
thread END
Beginning
of thread MyClassTwo !
Counter
of Class Two: =0
Counter
of Class Two: =1
Counter
of Class Two: =2
Counter
of Class Two: =3
Counter
of Class Two: =4
Counter
of Class Two: =5
Exit
from My Class Two !
Beginning
of thread MyClassThree !
Counter
of Class Three: =0
Counter
of Class Three: =1
Counter
of Class Three: =2
Counter
of Class Three: =3
Counter
of Class Three: =4
Counter
of Class Three: =5
Exit
from My Class Three !
Beginning
of thread My Class One !
Counter
of Class one: =0
Counter
of Class one: =1
Counter
of Class one: =2
Counter
of Class one: =3
Counter
of Class one: =4
Counter
of Class one: =5
Exit
from My Class One !
In the
starting of this program thread two started executing. But as thread started it
started executing even thread one was created first.
Implementing Runnable Interface
We have
created thread using Thread class in previous examples which is one method of
creating threads. Another method of creating a thread is by Implementing Runnables Interface. Steps
to create thread using Runnable:
1. Declare a class by implementing Runnable Interface.
2. Implement run() method
same as we have done using Thread class.
3. Create a thread by define an object of the class we have created.
4. Call start() method to
run the thread.
Example:
class MyClassOne implements Runnable // Step 1
{
public void run() // Step 2
{
System.out.println("Beginning of thread My Class One !");
for(int i=0; i<=3; i++)
{
System.out.println("Counter of Class one: =" + i);
}
System.out.println("Exit from My Class One !");
}
}
class MyClassTwo implements Runnable // Step 1
{
public void run() // Step2
{
System.out.println("Beginning of thread MyClassTwo !");
for(int i=0; i<=3; i++)
{
System.out.println("Counter of Class Two: =" + i);
}
System.out.println("Exit from My Class Two !");
}
}
public class ThreadExample
{
public static void main(String arg[]){
MyClassOne runableObjectOne = new MyClassOne();
MyClassTwo runableObjectTwo = new MyClassTwo();
Thread threadOne = new Thread(runableObjectOne); // Step 3
Thread threadTwo = new Thread(runableObjectTwo); // Step 3
System.out.println("Start thread one");
threadOne.start();
System.out.println("Start thread two");
threadTwo.start();
}
}
The output
of the program is:
Start
thread one
Start
thread two
Beginning
of thread My Class One !
Counter
of Class one: =0
Counter
of Class one: =1
Counter
of Class one: =2
Counter
of Class one: =3
Exit
from My Class One !
Beginning
of thread MyClassTwo !
Counter
of Class Two: =0
Counter
of Class Two: =1
Counter
of Class Two: =2
Counter
of Class Two: =3
Exit
from My Class Two !
No comments:
Post a Comment