|
|||||
Web
Design & Development CS506
VU
Lesson
23
Multithreading
Introduction
Multithreading
is the ability to do multiple things at
once with in the same
application. It provides
finer
granularity
of concurrency. A thread -- sometimes called an
execution context or a lightweight
process --
is a
single sequential flow of
control within a
program.
Threads
are light weight as compared
to processes because they
take fewer resources then a
process. A
thread is
easy to create and destroy.
Threads share the same
address space
i.e.
multiple threads can share
the memory variables directly, and
therefore may require more
complex
synchronization
logic to avoid deadlocks and
starvation.
Sequential
Execution vs Multithreading
Every
program has atleast one thread.
Programs without multithreading
executes sequentially. That is,
after
executing
one instruction the next instruction in
sequence is executed. If a function is
called then until the
completion
of the function the next instruction is
not executed. Similarly if there is a
loop then
instructions
after
loop only gets executed when
the loop gets completed. Consider the
following java program
having
three
loops in it.
//
File ThreeLoopTest.java
public
class ThreeLoopTest {
public
static void main (String args[ ])
{
//first
loop
for
(int i=1; i<= 5;
i++)System.out.println("first "
+i);
//
second loop
for
(int j=1; j<= 5;
j++)System.out.println("second " +
j);
//
third loop
for
(int k=1; k<= 5;
k++)System.out.println("third " +
k);
} // end
main} // end class
Note:
Each loop has 5 iterations
in the ThreeLoopTest program.
168
Web
Design & Development CS506
VU
Note:
Each loop has 10 iterations
in the ThreadTest program. Your output
can be different from
the one
given above.
Notice
the difference between the outputs of the two
programs. In ThreeLoopTest each loop
generated a
sequential
output while in ThreadTest the
output of the loops got
intermingled i.e. concurrency took
place
and
loops executed simultaneously
Let
us code our first
multithreaded program and try to
learn how Java supports
multithreading.
Java
includes built-in support for
threading. While other
languages have threads bolted-on to an
existing
structure.
i.e. threads were not the
part of the original language but
latter came into existence as the
need
arose.
All
well known operating systems
these days support multithreading. JVM
transparently maps
Java
Threads
to their counter-parts in the operating
system i.e. OS Threads. JVM allows
threads in Java to
take
advantage of
hardware and operating system level
advancements. It keeps track of
threads and schedules
them to get
CPU time. Scheduling may be
pre-emptive or cooperative. So it is the
job of JVM to manage
different
tasks of thread. Let's see
how we can create
threads?
Creating
Threads in Java
There
are two approaches to create
threads in Java.
Using
Interface
Using
Inheritance
Following
are the steps to create
threads by using
Interface:
1
Create
a class where you want to
put some code that
can run in parallel with
some other code and
let
that class implement the
Runnable interface
2
Runnable
interface has the run() method
therefore provide the implementation
for the run() method
and
put your code that
you want to run in parallel
here
169
Web
Design & Development CS506
VU
3
Instantiate
Thread class object by
passing Runnable object in
constructor
4
Start thread by
calling start() method
Following
are the steps to create
threads by using
Intheritance:
1
Inherit
a class from java.lang.Thread
class
2
Override
the run() method in the subclass
3
Instantiate
the object of the subclass
4
Start thread by
calling start() method
To
write a multithreaded program
using Runnable interface,
follow these steps:
· Step
1 - Implement the Runnable
Interface
class
Worker implements Runnable
· Step
2 - Provide an Implementation of run()
method
public
void run( ){// write thread
behavior// code that will be
executed by the thread
· Step
3 - Instantiate Thread class
object by passing Runnable
object in the constructor
Worker
w = new Worker("first");
Thread
t = new Thread (w);
·
Step 4
Start thread by calling
start() method
t.start();
Threads
Creation Steps Using
Inheritance
To
write a multithreaded program
using inheritance from
Thread class, follow these
steps:
Step 1
Inherit from Thread
Class
class
Worker extends Thread
Step 2
- Override run() method
public
void run( ){
//
write thread behavior
//
code that will execute by
thread
Step 3
- Instantiate subclass
object
Step 4
Start thread by calling
start() method
Worker
w = new Worker("first");
t.start();
So
far we have explored:
What
is multithreading?
What
are Java Threads?
Two
ways to write multithreaded Java
programs
Now
we will re-write the ThreeLoopTest
program by using Java
Threads. At first we will
use the Interface
approach
and then we will use
Inheritance.
Code
Example using
Interface
//
File Worker.java
public
class Worker implements
Runnable {
private
String job ;
//Constructor
of Worker class
public
Worker (String j ){
job =
j;
}
//Implement
run()
method of
Runnable
interface
public
void run ( ) {
for(int
i=1; i<= 10;
i++)System.out.println(job + " = " +
i);
170
Web
Design & Development CS506
VU
}
} //
end class
//
File ThreadTest.java
public
class ThreadTest{
public
static void main (String args[
]){
//instantiate
three objects
Worker
first = new Worker ("first
job");
Worker
second = new Worker ("second
job");
Worker
third = new Worker ("third
job");
//create three
objects of Thread class & passing
worker
//(runnable)
to them
Thread
t1 = new Thread (first
);
Thread
t2 = new Thread (second);
Thread
t3 = new Thread
(third);
//start
threads to execute
t1.start();
t2.start();
t3.start();
}//end
main} // end class
Following
code is similar to the code
given above, but uses
Inheritance instead of interface
//
File Worker.java
public
class Worker extends
Thread{
private
String job ;
//Constructor
of Worker class
public
Worker (String j ){
job =
j;
}
//Override
run()
method
of Thread
class
public
void run ( ) {for(int i=1;
i<= 10; i++)System.out.println(job + "
= " + i);
}
} //
end class
//
File ThreadTest.java
public
class ThreadTest{
public
static void main (String args[ ])
{
//instantiate
three objects of Worker (Worker class is
now
//becomes
a Thread because it is inheriting
from it)class
Worker
first = new Worker ("first
job");
Worker
second = new Worker ("second
job");
Worker
third = new Worker ("third
job");
//start
threads to execute
t1.start();
t2.start();
t3.start();
}//end
main} // end class
Threads
provide a way to write concurrent
programs. But on a single CPU,
all the threads do not
run
simultaneously.
JVM assigns threads to the CPU
based on thread priorities. Threads
with higher priority
are
executed in
preference to threads with lower
priority. A thread's default
priority is same as that of
the
creating
thread i.e. parent thread.
A
Thread's priority can be any
integer between 1 and 10. We can
also use the following
predefined
constants
to assign priorities.
171
Web
Design & Development CS506
VU
Thread.MAX_PRIORITY
(typically 10)
Thread.NORM_PRIORITY
(typically 5)
Thread.MIN_PRIORITY
(typically 1)
To
change the priority of a thread, we can
use the following method
setPriority(int
priority)
It
changes the priority of this thread to
integer value that is
passed. It throws an
IllegalArgumentException
if the
priority is not in the range
MIN_PRIORITY to MAX_PRIORITY i.e.
(110).
For
example, we can write the
following code to change a
thread's priority.
Thread
t = new Thread (RunnableObject);
// by
using predefined
constantt.setPriority
(Thread.MAX_PRIORITY);
// by
using integer constantt.setPriority
(7);
Thread
Priority Scheduling
The
Java runtime environment
supports a very simple,
deterministic scheduling algorithm
called fixed-
priority
scheduling. This algorithm
schedules threads on the basis of
their priority relative to
other
Runnable
threads.
At
any given time, when
multiple threads are ready
to be executed, the runtime system
chooses for
execution
the Runnable thread that has the
highest priority. Only when
that thread stops, yields
(will be
explained
later), or becomes Not
Runnable will a lower-priority thread
start executing. If two
threads of the
same
priority are waiting for the
CPU, the scheduler arbitrarily chooses
one of them to run. The
chosen
thread
runs until one of the following
conditions becomes
true:
A
higher priority thread becomes
Runnable.
It
yields, or its run() method
exits.
On
systems that support time-slicing,
its time allotment has
expired.
Then
the second thread is given a chance to
run, and so on, until the
interpreter exits. Consider the
following
figure in which threads of
various priorities are
represented by capital alphabets A, B,
..., K. A
and B
have same priority (highest in
this case). J and K have
same priority (lowest in
this case). JVM start
executing
with A and B, and divides CPU
time between these two
threads arbitrarily. When
both A and B
comes
to an end, it chooses the next thread C to
execute.
Code
Example: Thread
Properties
Try
following example to understand
how
JVM executes threads based
on
their
priorities.
//
File PriorityEx.java
public
class PriorityEx{ public
static
void
main (String args[ ]){
//instantiate
two objects
Worker
first = new Worker
("first
job");
Worker
second = new Worker
("second
job");
//create
two objects
Thread
t1 = new Thread (first
);
Thread
t2 = new Thread
(second);
//set
thread priorities
t1.setPriority
172
Web
Design & Development CS506
VU
(Thread.MIN_PRIORITY);
t2.setPriority
(Thread.MAX_PRIORITY);
//start
threads to execute
t1.start();
t2.start();
}//end
main} // end class
Output
Problems
with Thread Priorities
However,
when using priorities
with
Java
Threads, remember the
following
two
issues:
First
a Java thread priority may
map
differently
to the thread priorities of
the
underlying OS. It is because
of
difference
in priority levels of JVM
and
underlying OS. For
example
32
Solaris
has 2 1 priority
levels
Windows
NT has only 7 user
priority
levels
Second,
starvation can occur
for
lower-priority
threads if the higher-priority threads
never terminate, sleep, or
wait for I/O
indefinitely.
173
Web
Design & Development CS506
VU
References:
Java,
A Practical Guide by Umair
Javed
Java
How to Program by Deitel and
Deitel
CS193j
handouts on Stanford
174
Table of Contents:
|
|||||