Professional Documents
Culture Documents
U4 Java
U4 Java
UNIT-4, THREADS
What is a Thread
“A thread is a lightweight sub process, and the smallest unit of processing”. It is a separate path of
execution. A thread is similar to a program that has a single flow of control. It has a beginning, a
body, and an end, and executes commands sequentially. In fact main program in our programs
can be called as Thread.
Threads in java are subprograms of a main application program, they can share the same
memory space, and saves the CPU time, they are known as Lightweight Processes or Lightweight
Threads.
All the threads are running on a single processor, the flow of execution is shared between the
threads.
Benefits of threads:
It enables the programmers to do multiple things at one time.
Main method
module
switchin switchin
g g
A thread can be employed to execute one task at a time. Suppose there are 3 taks to be executed.
We can create a thread and pass the 3 tasks one by one to the thread.
For this purpose, we can write all these tasks separately in separate methods: task1(), task2(),
task3(). Then these methods should be called from run() method, one by one.
Remember, a thread executes only the code inside the run() method. It can never execute other
methods unless they are called i run ().
void task1()
{
System.out.println ("This is taks 1");
}
void task2()
{
System.out.println ("This is task 2");
}
void taxk3()
{
System.out.println("This is task 3");
}
class Single
{
public static void main(String args[])
{
MyThread obj= new MyThread();
Thread t1=new Thread(obj);
}
}
}
Output:
This is taks1
This is taks2
This is taks3
In multi tasking, several tasks are executed at a time. For this purpose, we need more than one
thread. For example, to perform 2 tasks, we can take 2 threads and attach them to the 2 tasks.
Then those tasks are simultaneously executed by the two threads. Using more than one thread is
called 'multi threading’.
When we go to a movie theatre, generally a person is there at the door-checking and cutting the
tickets. When we enter the hall, there is another person who shows the seats to us. Suppose there
is only one person (1 thread) doing these two tasks. He has to first cut the ticket and then come
along with us to show the seat. Then he goes back to the door to cut the second ticket and then
again enter the hall to show the seat for the second ticket. Like this, if he is does the things one by
one, it takes a lot of time, and even though the show is over, there will be still a few people left
outside the door waiting to enter the hall! This is pretty well known to the theatre management. So
what they do? They employ two persons (2 threads) for this purpose
The first person will cut the ticket, and the second one will show the seat. When the second person
is showing the seat, the first person cuts the second ticket. Like this, both the persons can act
simultaneously and hence there will be no wastage of time.
Program: Create a program showing two threads working simultaneously upon two objects.
//Two threads performing two tasks at a time-Theatre example
class MyThread implements Runnable
{
String str;
MyThreads(String str)
{
this.str=str;
}
The first method of creating a thread is simply by extending the thread class. The Thread class is
defined in the package java.lang.Thread. This gives access to all the thread methods directly. It
includes the following steps:
The run() method has been inherited by the class MyThread. This method order to
implement the code to be executed by our thread. The basic implementation of run() will look
like this:
{
………..
……….. // Thread code here
………..
}
When we start the new thread, Java calls the thread's run() method, so it is the run() method,
where all the action takes place.
3. Starting New Thread:
To actually create and run an instance of our thread class, we must write the following:
MyThread aThread = new MyThread( );
aThread. start(); // invokes run() method
The first line instantiates a new object of class MyThread. This statement just creates the
object. The thread is in a newborn state.
The second line calls the start() method causing the thread to move into the runnable state.
Example program:
import java.lang.*;
class A extends Thread
{
public void run()
{
for(int i=1;i<=5; i++)
{
System.out.println("\tFrom ThreadA: i=” +i);
}
System.out.println("Exit form A);
}
}
class ThreadTest
{
The Runnable interface declares the run() method that is required for implementing threads in
our programs. To do this, we must perform the steps listed below.
Example:
class XYZ implements Runnable
{
public void run()
{
for(int i=1;i<10; i++)
{
System.out.println("Thread XYZ:” +i);
}
System.out.println("End of ThreadXYZ");
}
}
class RunnableTest
{
public static void main(String args[])
{
XYZ runnable= new XYZ();
Thread tx=new Thread(runnable);
tx.start();
System.out.println(“End of main Thread”);
}
}
boolean stop=false;
2. Let us assume that we want to terminate the thread when the user presses <Enter> key. So,
when the user presses that button, make the boolean type variable as true
stop = true;
3. Check this variable in run() method and when it is true, make the thread return from the run()
method.
if (stop ==true)
return;
}
Program : How to terminate the thread by pressing the Enter button.
class Demo1
{
public static void main(String args[]) throws IOException
{
MyThread obj = new MyThread();
Thread t = new Thread (obj);
t.start();
System.in.read();
obj.stop()=true;
}
}
Output:
Take the case of railway reservation. Every day several people want reservation of a berth for
them. The procedure to reserve the berth is same for all the people. So we need same object
with same run() method to be executed repeatedly for all the people (threads).
Let us think that only one berth is available in a train, and two passengers (threads) are asking for
that berth. In reservation counter no.1, the clerk has sent a request to the server to allot that
berth to his passenger. In counter no.2, the second clerk has also sent a request to the server to
allot that berth to his passenger. Let us see now see to whom that berth is allotted.
Program: Create a program showing two threads acting upon a single object.
{
int available=1;
int wanted;
Reserve (int i)
{
wanted = i;
}
public void run()
{
System out.println ("Available Berths="+available);
if(available>= wanted)
{
string name= Thread.currentThread(). getName();
System.out.println(wanted+" Berths reserved for "+name);
try{
Thread.sleep(1500); // wait for printing the ticket
available =available - wanted;
}
catch (InterruptedException ie)
{}
} else System.out.println ("Sorry, no berths");
}
}
class Unsafe
{
Reserve obj = new Reserve (1);
Thread t1= new Thread (obj);
Thread t2= new Thread(obj);
t1.setName ("First person");
t2.setName ("Second person");
t1.start();
t2.start();
}
Output:
Available Berths = 1
1 Berths reserved for First Person
Available Berths = 1
1 Berths reserved for Second Person
Deadlock Example
First, let's take a look into a simple Java example to understand deadlock. In this example, we'll
create two threads, T1 and T2. Thread T1 calls operation1, and thread T2 calls operations.
1. public class TestDeadlockExample1 {
2. public static void main(String[] args) {
3. final String resource1 = "ratan tata";
4. final String resource2 = "vimal tata";
5.
6. Thread t1 = new Thread() { // t1 tries to lock resource1 then resource2
7. public void run() {
8. synchronized (resource1) {
9. System.out.println("Thread 1: locked resource 1");
10.
11. try { Thread.sleep(100);}
12. catch (Exception e) {}
13. synchronized (resource2) {
14. System.out.println("Thread 1: locked resource 2");
15. } } } };
16.
17. Thread t2 = new Thread() { // t2 tries to lock resource2 then resource1
18. public void run() {
19. synchronized (resource2) {
20. System.out.println("Thread 2: locked resource 2");
21.
22. try { Thread.sleep(100);}
23. catch (Exception e) {}
24. synchronized (resource1) {
25. System.out.println("Thread 2: locked resource 1");
26. } } } };
27. t1.start();
28. t2.start();
29. } }
Once we run the program, we can see that the program results in a deadlock and never exits. The log
shows that thread T1 is waiting for lock2, which is held by thread T2. Similarly, thread T2 is waiting
for lock1, which is held by thread T1.
Avoiding Deadlock
Deadlock is a common concurrency problem in Java. Therefore, we should design a Java application
to avoid any potential deadlock conditions.
We improve the efficiency of communication between threads. Java.lang. Object class provides
3 methods for this purpose.
1. notify():
This method releases an object (obj) and sends a notification to a waiting thread that the
object is available.
Ex: public final void notify()
2. notifyAll():
This method is useful to send notification to all waiting threads at once that the object (obj) is
available.
Ex: public final void notifyAll()
3. wait():
This method makes a thread wait for the object (obj) till it receives a notification from a
notify() or notify All() methods. It is recommended to use the above methods inside a
synchronized block.
Method Description
public final void wait() throws InterruptedException It waits until object is notified.
public final void wait(long timeout) throws It waits for the specified amount of time.
InterruptedException
Java permits us to set the priority of a thread using the setPriority() method as follows.
ThreadName.setPriority(Number);
The Number is an integer value to which the threads priority is set. The Thread class defines several
priority constants of 3 types that is.
The Number may assume one of these constants or any value between 1 and 10. The default setting
is NORM _ PRIORITY.
Whenever multiple Threads are ready for execution, the Java system chooses the highest priority
thread and executes it. For a thread of lower priority to gain control, one of the following things
should happen.
class as:
Here we are creating and adding the thread group tg1 to the thread group tg. The name of the
added thread group is represented by groupname.
4. To know the parent of a thread or a thread group, we can use getParent().
tg.getParent ();
This method returns ThreadGroup object which is the parent of tg.
5. To know the parent thread group of a thread, we can use:
t.getThreadGroup();
This return a ThreadGroup object to which the thread t belongs.
6. To know the number of threads actively running in a thread group :
tg.setMaxPriority ();
Normally, the maximum priority of a thread group will be 10. But this method can set it as any other
number between 1 and 10.
Example: To demonstrate the creation of thread groups and some methods which act on thread
groups.
class TGroups
{
public static void main(String[] args) throws Exception
{
Reservation res = new Reservation ();
Cancellation can = new Cancellation ();
A daemon thread is a thread that executes continuously. Daemon threads are service providers for
other threads (or) objects. It generally provides a background processing
A thread is always in one of these five states. It can move from one state to another via a variety
of ways as shown in below figure.
1. NewBorn State
When we create a thread object, the thread is born and is said to be in newborn state. The
thread is not yet scheduled for running. At this state, we can do only one of the following
things with it:
Schedule it for running using start() method
2. Runnable State
The Runnable state means that the thread is ready for execution and is waiting for the
availability of the processor. If all the threads have equal priority, then they are given time
slots for execution in first-come, first-serve manner. If we want a thread to relinquish (hand
over) control to another thread to equal priority before its turn comes, we can do so by using
the yield().
3. Running State
Running means that the processor has given its time to the thread for its execution. The
thread runs until it loses control on its own or it is preempted by a higher priority thread. A
Thread may be control its control in one of the following situations.
A thread is said to be Blocked when it is prevented from entering into the runnable state
and subsequently the running state. This happens when the thread is suspended, sleping, or
waiting in order to satisfy certain requirements. A blocked thread is considered “not
runnable” but not dead and therefore fully qualified to run again.
5. Dead State
Every thread has a lifecycle. A running thread ends its life when it has completed executing
its run() method. It is natural death. However, we can kill it by sending the stop message to it
at any state thus causing a premature death to it. It is done by stop() method.
Thread class also defines many methods for managing threads. Some of them are,
Method Description
1)setName() to give thread a name
2)getName() return thread's name
3)getPriority() return thread's priority
4)isAlive() checks if thread is still running or not
5)join() Wait for a thread to end
6)run() Entry point for a thread
7)sleep() suspend thread for a specified time
8)start() start a thread by calling run() method
Returns an estimate of the number of active threads in
9)activeCount()
the current thread's thread group and its subgroups.
Determines if the currently running thread has
10) checkAccess()
permission to modify this thread.
Returns a reference to the currently executing thread
11) currentThread()
object.
Prints a stack trace of the current thread to the
12) dumpStack()
standard error stream.
13) getId() Returns the identifier of this Thread.
14) getState() Returns the state of this thread.
15) getThreadGroup() Returns the thread group to which this thread belongs.
Method Description
16) interrupt() Interrupts this thread.
17) interrupted() Tests whether the current thread has been interrupted.
18) isAlive() Tests if this thread is alive.
19) isDaemon() Tests if this thread is a daemon thread.
20) isInterrupted() Tests whether this thread has been interrupted.
21) setDaemon(boolean Marks this thread as either a daemon thread or a user
on) thread.
22) setPriority(int
Changes the priority of this thread.
newPriority)
A hint to the scheduler that the current thread is willing
23) yield()
to yield its current use of a processor.