Multithreading
Introduction:
It
is one of the important features of Java that allows us to run two different
parts of the program concurrently by sharing the common resources of the
system.
A
Thread is a lightweight component that is similar to a program.
Multithreading
is a conceptual programming where a program is divided into two or more
processes which can be implemented at the same time in parallel.
Ex:- In a MS-Word we can modify the
document on the foreground, at then we can send the job of printing at the background.
Keypoints:
- By default every
java program is under the implementation of main
- thread.
- Each thread has a
main and a priority
- Threads has to be
started explicitly.
- Threads can be
synchronized.
- Threads can be
intercommunicated.
Creating Threads:
1. By extending from
Thread Class
2. By implementing a
Runnable Interface.
If
it requires extending from more than one class, then we have to implement the
Runnable interface, since Java classes cannot have two superclass. It depends
on the classes we create. Otherwise we can use Thread Class. The Runnable
interface has only one method, run().
By extending from Thread Class:
class
classname extends Thread
{
Thread () { } //
Thread constructor if required
public void run()
{
-------
-------
}
}
To start the Thread:
For example we take classname is
ABC
ABC
a=new ABC();
a.start();
Ex:
class
ABC extends Thread
{
public void run()
{
System.out.println("Welcome
to the concept of Threads");
}
}
class
xx
{
public static void main(String
[]args)
{
ABC a=new ABC();
Thread t=new
Thread(a);
t.start();
}
}
By implementing a Runnable
Interface:
- Declare the class
as implementing the Runnable interface
- Implement the
run() method
- Create a thread
by defining an object that is instantiated from this 'runnable' interface
- Call the threads
start() method to run the thread.
Ex:
class
y
{
int
bal=100;
}
class
x implements Runnable
{
y
p;
int
r;
int
sleepValue;
x(int
a,int b, y g)
{
r=a;
sleepValue=b;
p=g;
}
public
void run()
{
if(p.bal>r)
{
System.out.println("fund
is available");
p.bal=p.bal-r;
System.out.println("Got
it!!!"+Thread.currentThread());
synchronized(p)
{
try
{
Thread.sleep(sleepValue);
}
catch
(Exception e){}
}
else
{
System.out.println("Insufficient
bal "+Thread.currentThread());
}
}
}
class
Thread2
{
public
static void main(String args[])
{
y=new
y();
x
job1=new x(50,1000,n);
x
job2=new x(80,0,n);
Thread
t1=new Thread(job1,"job1");
Thread
t2=new Thread(job2,"job2");
t1.start();
t2.start();
}
}
Stopping and Blocking a Thread:
Stopping Thread:
whenever
we want to stop a thread from running further, we may do so by calling its
stop() method, like
Thread.stop();
The
stop() may be used when the premature death of a thread is needed.
Blocking a Thread:
A
thread can also be temporarly suspended or blocked from the runnable or running
state by
sleep() // blocked for a specified time
suspend() //blocked until further orders
wait() //blocked until certain condition occurs
Again
the thread enters into the running state from blocked state by resume() method
in case of suspend() and the notify() method is called in the case of wait().
Life Cycle of a Thread:
Stages
occured during the Life Cycle of a Thread
- Newborn State
- Runnable State
- Running State
- Blocked State
- Dead State
Newborn State:
When
we create a thread object, the thread is born and is said to be in newborn
state. At this state, we can do only one of the following things with it:
- schedule it for
running using start() method
- kill it using
stop() method
If
scheduled it moves to the runnable state.
Runnable State:
The
runnable state means that the thread is ready for execution and is waiting for
the availability of the processor. That is, the thread has joined the queue of
the threads that are waiting for execution. If we want a thread to
relinquish(give up) control to another thread of equal priority before it turn
comes, we can do so by using the yield() method.
Running State:
1.
It has been suspended using suspend () method. A suspended thread can be
revived by using the resume() method.
2.
It has been made to sleep. We can put a thread to sleep for a specified time
period, where time is in milliseconds. This means that the thread is out of the
queue during this time period. The thread re-enters the runnable state as soon
as this time period is elapsed.
3.
It has been told to wait until some event occurs. The thread can be scheduled
to run again using the notify() method.
Blocked State:
Dead State:
Thread Class Methods:
Some
commonly used methods of Thread Class are:
Method
Name
|
Description
|
Static
Thread currentThread()
|
Returns
a reference to the currently executing thread object.
|
String
getName()
|
Returns
the name of the thread in which it is called.
|
int
getPriority)
|
Returns
the thread priority
|
Void
interrupt()
|
Used
for interrupting the thread
|
Void
setName(String Newname)
|
Changes
the name of the thread to new name
|
Void
setPriority()
|
Changes
the thread priority
|
Static
void sleep(long millisec)
|
Causes
the currently running thread to sleep
|
Void
start()
|
Used
to begin the execution of a thread. It calls the run()
|
Static
void yield()
|
Used
to pause temporarily to current thread object and allows other thread to
execute
|
String
toString()
|
Returns
a string representation of thread. String includes threadgroup, threadsname
and priority
|
Void
destroy()
|
Destroys
the thread without any cleanup.
|
Thread Exceptions:
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:
catch(ThreadDeath e)
{
|
-----
}
catch(InterruptedException e)
{
-----
-----
}
catch( )
{
-----
-----
}
catch( )
{
-----
-----
}
Thread Priorities:
Java assigns to each thread a priority. Thread priority is
an integer that specifies the relative priority of one thread to another. A
thread can voluntarily relinquish its control. Threads relinquish control by
explicitly yielding, sleeping, or blocking on pending Input/ Output operations.
In this scenario, all other threads are examined, and the highest- priority
thread that is ready to run gets the chance to use the CPU.
A higher-priority thread can pre-empt a low priority thread. In
this case, a lower- priority thread that does not yield the processor is
forcibly pre-empted. In cases where two threads with the same priority are
competing for CPU cycles, the situation is handled differently by different
operating systems.
Java thread class has defined two constants MIN_PRIORITY and
MAX_PRIORITY. Any thread priority lies between MIN_PRIORITY and MAX_PRIORITY.
Currently, the value of MIN_PRIORITY is 1 and MAX_PRIORITY is 10.
The priority of a thread is set at the time of creation. It is set
to the same priority as the Thread that created it. The default priority of a
thread can be changed by using the setPriority( ) method of Thread class.
Final void setPriority (int Priority_Level) where Priority_Level
specifies the new priority for the calling thread.
To return a thread to default priority, specify Norm_Priority,
which is currently 5.
You can obtain the current priority setting by calling the
getPriority( ) method of thread class.
final int getPriority( ).
//program
class Thread_Priority
{
public static void main (String args [ ])
{
try
{
Thread Td1 = new Thread ("Thread1");
Thread Td2 = new Thread ("Thread2");
System.out.println ("Before any change in default
priority:");
System.out.println("ThePriority
of "+Td1.getName() +" is "+ Td1.getPriority());
System.out.println("The Priority of "+Td1.getName()
+" is "+ Td2.getPriority());
//change in priority
Td1.setPriority(7);
Td2.setPriority(8);
System.out.println ("After changing in Priority:");
System.out.println("The Priority of "+Td1.getName()
+" is "+ Td1.getPriority());
System.out.println("The
Priority of "+Td1.getName() +" is "+ Td2.getPriority());
}
catch ( Exception e)
{
System.out.println("Main thread interrupted");
}
}
}
Output:
Before any change in default priority:
The Priority of Thread1 is 5
The Priority of Thread1 is 5
After changing in Priority:
The Priority of Thread1 is 7
The Priority of Thread1 is 8
Synchronization:
It
is the process of running only one thread (or) one resource by making other
threads to be wait in the queue. Synchronization is achieved with the help of
an object called monitor which allows only one thread to enter by making other
threads to wait. Once the thread in the monitor has completed the job either
the next thread or thread based on higher priority will be executed.
Synchronization is achieved in java with the help of a method called
Synchronized() which can be applied either for methods (or) statements.
Ex:
While
printing job has been assigned from different systems simultaneously, the
task should be done serially otherwise
it may results to wrong prints. We make the
printing method synchronized such that the task will be done serially.
class
SynchronizeDemo2
{
public static void main(String
args[])
{
Shared shared = new
Shared();
CustomThread thread1 =
new CustomThread(shared, "one");
CustomThread thread2 =
new CustomThread(shared, "two");
CustomThread thread3=new
CustomThread(shared, "three");
CustomThread thread4 =
new CustomThread(shared, "four");
try
{
thread1.join();
thread2.join();
thread3.join();
thread4.join();
}
catch(InterruptedException
e) {}
}
}
class
CustomThread extends Thread
{
Shared shared;
public CustomThread(Shared shared,
String string)
{
super(string);
this.shared = shared;
start();
}
public void run()
{
shared.doWork(Thread.currentThread().getName());
}
}
class
Shared
{
synchronized void doWork(String string)
{
System.out.println("Starting
" + string);
try
{
Thread.sleep(1000);
}
catch
(InterruptedException e) { }
System.out.println("Ending
" + string);
}
}