Thread is a function under execution. Normally Threads are used for multitasking.
Multitasking: - Concept o of executing more than one
function at a time is known multitasking.
Multitasking came into picture to avoid the idle state of
cpu.
IdleState of cpu :-
Suppose there are 3 functions in a class
class
Example
{
void
function1( )
{ }
void
function2( )
{ }
void
function3( )
{ }
public static void main(String[] args) {
Example
e= new Example( );
e.function1( );
e.function2( );
e.function3( );
} }
|
Explanation:
·
In this example the functions are called one
by one as above after completion of function1()
only function2() will be executed. After the successfully execution of
function2() only function3 will be executed. That means
function2() execution depends on the execution of function1(),and
function3() execution depends on the execution of function2().
·
Suppose there are datatransfer statements as
part of cpu, it is responsibility of a DMA to execute datatransfer statements. So cpu will assign the task of
datatransfer to DMA to eecute statements in funcion1()
·
Meanwhile the Processor(cpu) will remains
idle.Thease state of cpu is known as “ Idle state of cpu ”.
·
Developers thinks that if we assign a some
other task to cpu during idle state, we can improve the performance of cpu.This
thought come here for birth of multitasking.
There are 2 types of multitasking
1. Process based
multitasking :- Concept of executing more than one programs
simultaneous
belonging to different memory domain is
known as “ process based multitasking “.Process is a program under execution.
2. Thread based
multitasking:- Concept of executing more than one functions
simultaneously
belonging to same memory domain is known
as “ Thread based multitasking “(with in same program). Thread is a function
under execution which is executing along with other functions.
To enable any function to be executed as a thread, we
have to follow 2 conditions.
1.
Implement a thread functionality.
2. Enable that implemented
functionality to be executed as a thread functionality.
There are 2 ways to implement the thread functionality
1.
Extending a Thread
class.
2. Implementing the
Runnable Interface.
Whatever may be the approach we have to override a run()
method. Overriding run() is compalsary
to achieve thread functionality.
Ex: (Extending a thread class)
class ThreadA extends Thread {
public void run()
{
System.out.println(“inside run() of threadA”);
for (int i=0; i<=10; i++) {
System.out.println(“the i values are
: “+ i); } }
public static void main(String[] args) {
ThreadA ta=new
ThreadA();
ta.start(); }
}
|
Explanation : To achieve a
thread functionality, we have to call a start() method available in
thread class which will make run() available to the local operating system will
be executed as a thread.
1st
Approach:
Ex:
(executing three threads simultaneously)
class ThreadA extends Thread {
public void method() {
for(int i=0;i<50;i++) {
System.out.println(“ThreadA method : ” +i ); }
}
public void
run() {
method(); } }
class ThreadB extends Thread {
public void run() {
for(int x=50;x<100;x++) {
System.out.println(“ThreadB method :” +x); }
} }
class ThreadC extends Thread {
public void run() {
for(int y=100;y<150;y++) {
System.out.println(“ThreadB method :” +y); }
}
public static void main(String[] args) {
Thread A ta=new ThreadA();
ta.start();
//ta.run();
ThreadB ta=new ThreadB();
tb.start();
//tb.run();
ThreadC ta=new ThreadC();
tc.start();
//tc.run(); }
}
|
Explanation:
·
If we call a run() method directly ,run()
will be getting executing as normal
function. If we call a start() method on any object, start() will hand over the
run() of that object to the local operating system, which will be executed as a
thread.
·
In the above program, we can’t expect the
output of program. Because all functions
are threads here . They will getting
executed simultaneously(at a time) .
·
Scheduler will decide the time of each
function execution, while the function is executing as a thread. Here functions
will be executed independently.
·
To execute any functions as a threads, we
have to call the functions from the run() method .
·
To define multiple threads, we have to define
those many thread classes as required.
·
From different run() methods of
different thread classes we have to call
the required functions which we need to be executed as a threads. Because one
thread class contains one run() only.
2nd Approach:
Ex: (
Implementing Runnable Interface )
class MyThread
implements Runnable {
void run() {
for(int
z=0;z<5;z++)
{ Syatem.out.println(“Mythread class”
+z); } }
public static void main(String[] args) {
MyThread mt=new
MyThread();
Thread t=new Thread(mt);
t.start();
} }
|
Explanation: if our class is implementing a Runnable
interface, then to enable class functions to be executed as a thread, we have
to follow below 2 steps while calling methods.
1. create
object of our class (Runnabla obj) (Runnable r=new
Implementaton())
2. Create
Thread class object bypassing Runnable object as a constructor , then call
start() method on Thread class object.
(Q) How can we make one class object available
to other class without extending ?
(A)
Using Parameterised constructor.
(Q) If
our class is extending the another class, how can we implement the Thread
functionality ?
(A)We have to use “ implements Runnacle “to our class.
Ex:
class A {
void functonA() {
System.out.println(“funA of class A”); }
class MyThread extends A
implements Runnable {
void MyFunction() {
for(int i=0;i<50;i++) {
System.out.println(“
MyThread “); } }
public void run()
{
MyFunction(); }
public static void main(String[] args) {
MyThread mt=new
MyThread();
Thread t=new Thread(mt);
t.start(); }
}
|
We can suspend a thread based on 3 criterias
1. Suspending a Thread based on time:-
There is a static method (sleep() )
available in Thread class, where we can suspend a thread for required amount of
time .( public static native void sleep(long) throws InterruptedException )
This method accepts time in terms of
milliseconds. This method is proven to generate checked exception
(InterruptedException ).So we have to call this method always inside the
try-catch block. Otherwise it will give as error.
2. Suspending a Thread based on condition:
We have a join() method available in
Thread class to suspend a thread based
on condition.
”
final Synchronized void join()
“ throws java.lang.InterruptedException.
Suppose if we have 3 threads t1,t2,t3.
If we have condition that run() of t3
should be executed only after the values
calculated from the run() of t1 . In this
situations, we have to call the join() method inside run() of t3, which will enables the
complete execution of t1 thread
before execution of t3 thread.
3. Suspending a thread unconditionally:
We have a non-static suspend() method available in Thread class,
to suspend a thread unconditionally(without any condition). The suspended
thread will not be reinitialised until and unless it is resumed ( resume()
method available in Thread class has
called ). This methods are deprecated with current version of java(java 5.0).
The alternative methods are wait(),notify() methods available in java.lang.Object
class.
Ex: (for
sleep()method)
class Thread1
extends Thread {
public void run() {
System.out.println(“run method of
Thread1”);
try {
Thread.sleep(5*1000);
} catch(InterruptedException ie)
{ ie.printStackTrace(); }
for(int a=0;a<20;<a++) {
System.out.println(“ thread1 values are: “+a);
} }
public static void
main(String[] args) {
Thread1 t1=new
Thread1();
t1.start(); }
}
|
Explanation:
1. In this program, instead of handling the
Exception in run() we can declare using throws. if we are declaring a run()
with throws InterruptedException, then we are absolutely violating the concept
of overriding.
[ public void run()throws
InterruptedException ]
2. Concept
of overriding says that we have to
define a same method with same signature in the sub class.
3. main()
method is also a thread. Here in the above program 2 threads are there
(main(),Thread1 )
4. So
using a sleep() , we can suspend a thread based on time.
Ex: (
for join() method )
class ThreadA extends Thread {
int sum;
public void run( )
{
for (int i=0;i<16;i++) {
sum=sum+1;
System.out.println("Thread1 values: "+sum); }
} }
public class Test {
public static void main(String[] args) {
ThreadA a=new ThreadA();
ThreadB b=new ThreadB();
ThreadC c=new
ThreadC(a);
a.start();
c.start(); }
}
|
class ThreadB extends Thread {
public void run()
{
for (int j=5;j<10;j++) {
System.out.println("Thread1 j values: "+
j); } }
}
class ThreadC extends
Thread {
int res;
ThreadA a;
ThreadC(ThreadA a) {
this.a=a; }
public void run()
{
for (int k=10;k<20;k++) {
if (k==15) {
try
{
a.join();
}
catch (InterruptedException e)
{
System.out.println(e.getMessage());
}
//catch close
res=a.sum-k;
System.out.println("result is :" +res); }
} } }
|
Q) If a main() completes its execution first,
then how remaining threads will be executed ?
A)
All the threads inside the main() is
“ default joined “.
Thread
Safety:-
Concept of avoiding multiple threads acting upon the same
function is known as “Thread Safety
” or “ Thread Synchronized “.
class Common {
synchronized void function1(String
s) {
System.out.println(“hello”);
try
{ Thread.sleep(3*1000);
} catch(InterruptedException e) {
e.printStackTrace(); }
System.out.println(“[“+s+”]world”); }
}
class Thread1 extends Thread {
Common c1;
Thread1(Common c1) {
this.c1=c1; }
public void run() {
c1.function1(“java”);
} }
class Thread2 extends Thread {
Common c1;
Thread2(Common c1) {
this.c1=c1; }
public void run() {
c1.function1(“c++”); } }
class Test {
public static void main(String[] args) {
Common c1=new Common();
Thread1 t1=new
Thread1();
Thread2 t2=new
Thread2();
t1.start();
t2.start(); }
}
|
Explanation:
1. In
the above program, we have a class Common which has a function1()
2. If
we call this function1() ( without synchronized block ) from 2 threads t1,t2
by passing inputs “Java”, ”c++”
thease will get the output as below.
OUTPUT: hello hello [java]world
[c++]world
3. Because
2 threads are acting upon the same function at the same time. So we are getting
improper outputs which are not correct.
4. If
we use a synchronized keyword to define a function then only one thread can
execute the entire function at a time.ie, we have provided the tread safety
by using synchronized keyword.
5. Synchronization
the process of avoiding the multiple threads acting upon the same function.
Differences b/w normal functions & thread safety functions:
1. Suppose,
we have a function with 100 lines of statements, among 100 lines 4 lines has a
user specific functionality. Thease 4
statements should be different for different users.
2. Then
we can provide the thread safety only for 4 statements using synchronized keyword.
Syntax: Function1() {
// statements
Synchronized {
// statements } }
wait() :-
It is a method available in Object class. we can use a wait() method to
suspend a thread until it notified
( by using notify() method ). Scheduler will schedule the time of
execution of each thread normally. We can partially control the schedule
processing using wait() and
notify().wait() should be called always inside the Synchronized block.
notify() :- It
is method available in Object class. We can use this method to resume the
suspended thread.
Ex:
class Common {
int value;
boolean flag=true;
synchronized
void produce(int i) {
this.value=i;
System.out.println(“producer prodused value” +i);
flag=false;
notify();
try
{
wait();
}
catch(InterruptedException e)
{
e.printStackTrace(); }
}
synchronized int
consume()
{
if(flag==true)
{
try
{
wait();
}
catch(InterruptedException e)
{
e.printStackTrace(); }
}
else {
notify();
flag=false; }
return value;
} }
class Producer extends Thread {
Common c;
Producer(Common c) {
this.c=c; }
public void run() {
int i=0;
while(true) {
c.produce(i);
i++;
try {
Thread.sleep(1800);
} catch(InterruptedException e) {
} } } }
class Consumer extends Thread {
Common c;
Consumer(Common c)
{
this.c=c; }
public void run() {
int j=0;
while(true) {
j=c.cosume(j);
i++;
System.out.println(“consumer has consumed”);
try {
Thread.sleep(1800);
} catch(InterruptedException e) {
} } } }
class Test {
public static void main(String[] args) {
Common c=new Common();
Consumer cth=new
Consumer(c);
Produser pth=new Produser(c);
cth.start();
Pth.start(); } }
|
Explanation:
·
We cannot control the scheduling process of
scheduler, but we can partially control the scheduling using wait() and
notify() available in object class.
·
In the above program our requirement is
1. producer
will produce a value and producer, thread will wait till consumer will consume
the
produced value.
2. Consumer will consume a value produced and it will
wait till the next value produced.
·
To do above task we have to establish the
communication between two threads, that is producer has to communicate with
consumer, and consumer has to communicate with producer, this process is known
as “interthread communication”.
·
We can achieve “interthread communication”
using wait() and notify() methods.
Q. Why should we call notify() before wait() is
called?.
Ans: Suppose there are two threads t1 and
t2, if we are asking the t2 to wait and if t1 is already in wait state, then we
con’t achieve anything. So if we call notify() method, if already some thread
in wait() state that will be resumed back to initial state.
Properties of a thread:
·
If we have many threads which are in wait()
state, when we notify() the threads, a thread which has highest priority will
be notified first. The priority of main thread is “s”
·
Each thread will be assigned with a priority
by the JVM.
·
If we want to assign a priority to our
threads, we have a method setpriority() in thread class. t1.setpriority(6); this
value lies between 0 to 9
0 is thread as the lower priority.
9 is thread as the higher priority.
DeadLock of Threads:
It is the situation when the threads will lock forever
because of circular dependency b/w two or more threads.
1. Suppose,
if we have two classes x, y with methods mone(), mtwo() which are synchronized.
2. Suppose
t1 is acting upon the mone() and t2 acting upon the mtwo().
3. Both
methods are synchronized methods.
4. Now,
if we call the mtwo() from mone(),
mtwo() will not be executed. Because
already t2 thread is acting upon the mtwo() and also two() is synchronized
method .
5. If we
call the mone() from mtwo(), mone() method will not be executed. Because thread
t1 is already acting upon the mone() and also tone() is synchronized method.
6. So,
these two methods will not be executed forever. This situation is known as “
DeadLock of threads ”. Here there is a circular dependency b/w two threads.
7. DeadLock
situation is a very dangerous in our application. Because it is performance hit
on our application.
8. suspend() , resume() methods were causes DeadLock situation.
So thease two methods are deprecated from the current version.
Deamon Threads:- A thread which is running in while loop,
which starts its execution along with its parent thread and stops execution along with its parent thread is
known as “Deamon Thread”.
Ex: Garbage
Collector is a Deamon Thread.
Garbage Collector:-
1. It
is thread which is running in infinit loop (while loop). It is starts
execution along with the main thread and stops execution when main
thread stops.
2. It
is a background process which will run along with main thread to free the
memory from the objects which are no long referenced (which are not used in the
program).
3. It
is automatic process which will nullify the objects that are not used in the
program.
4. We
can ask garbagecollector to garbagecollect the objects using “ System.gc() “ method.
5. When
we call the gc() method, garbagecollector will accept that as just instruction.
But it will not garbagecollect the object immedietly.
6. It
is an algorithm. It contains some process.
To convert normal
threads as Deomon threads :
Ex:
class Deamon1 extends Thread {
public void run() {
int i=0;
while(true) {
System.out.println(“Deamon1 thread : : “ +i);
i++; } }
public static void main(String[] args) {
Deamon1 dm=new
Deamon1();
d.setDeamon(true);
d.start();
for(int i=50;i<=90;i++) {
System.out.println(“parent thread
: : “ +i); } } }
|
Life Cycle of Threads:
1. Thread
will under go different changes during the life cycle of a thread.
2. If,
thread is running we can say that thread
is alive.
3. When
we start a thread it will go to ready to run state(runnable state).
4. Based
on scheduling times the requested threads will enter into the running state.
5. We
can suspend a thread using sleep(), wait(),suspend() methods
6. Suspended
threads can be resumed to go back to running state from where it has stoped.
7. Finally,
threads will completes its execution and it will be terminated, this is known
as
“ deadstate of thread “.
8. Once
the thread is terminated we can’t get back to running state.
9. We
have a method isAlive() o check whether the thread is alive or not.
This method returns “ true “, if the
thread is alive
This method returns “ false “, if the thread is not alive.
yield() :- If we have the threads with same priority,
then we can stop the execution of the current thread tempararly using yield().
Using yield() method we can move thread from running state to runnable state.
No comments:
Post a Comment