You are on page 1of 43

SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

Multi Threading and Generic Programming    4.1

UNIT-4

MULTI THREADING AND GENERIC PROGRAMMING

4.1 Multithreading and Multi-Tasking


In programming, there are two main ways to improve the throughput of a program:
i) by using multi-threading
ii) by using multitasking
Both these methods take advantage of parallelism to efficiently utilize the power of CPU
and improve the throughput of program.
ET
Difference between multithreading and multi-tasking
1. The basic difference between multitasking and multithreading is that in multitasking,
the system allows executing multiple programs and tasks at the same time, whereas,
in multithreading, the system executes multiple threads of the same or different pro-
C
cesses at the same time.
2. Multi-threading is more granular than multi-tasking. In multi-tasking, CPU switches
SV

between multiple programs to complete their execution in real time, while in multi-
threading CPU switches between multiple threads of the same program. Switching
between multiple processes has more context switching cost than switching between
multiple threads of the same program.
3. Processes are heavyweight as compared to threads. They require their own address
space, which means multi-tasking is heavy compared to multithreading.
4. Multitasking allocates  separate memory and resources  for each process/program
whereas, in multithreading threads belonging to the same process  shares the same
memory and resources as that of the process.

CS8392 OBJECT ORIENTED PROGRAMMING 1


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

Comparison between multithreading and multi-tasking


Parameter Multi Tasking Multi Threading
Basic Multitasking lets CPU to execute Multithreading lets CPU to execute
multiple tasks at the same time. multiple threads of a process simul-
taneously.
Switching In multitasking, CPU switches In multithreading, CPU switches
between programs frequently. between the threads frequently.
Memory and In multitasking, system has to In multithreading, system has to
Resource allocate separate memory and allocate memory to a process,
resources to each program that multiple threads of that process shares
CPU is executing. the same memory and resources
allocated to the process.
Multitasking
Multitasking is when a single CPU performs  several tasks (program, process, task,
threads)  at the same time. To perform multitasking, the CPU switches among these tasks
ET
very frequently so that user can interact with each program simultaneously.
In a multitasking operating system, several users can share the system simultaneously.
CPU rapidly switches among the tasks, so a little time is needed to switch from one user to the
next user. This puts an impression on a user that entire computer system is dedicated to him.
C
SV

Figure: Multitasking
When several users are sharing a multitasking operating system, CPU scheduling and 
multiprogramming  makes it possible for each user to have at least a small portion of
Multitasking OS and let each user have at least one program in the memory for execution.

CS8392 OBJECT ORIENTED PROGRAMMING 2


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

Multi threading
Multithreading is different from multitasking in a sense that multitasking allows mul-
tiple tasks at the same time, whereas, the Multithreading allows multiple threads of a single
task (program, process) to be processed by CPU at the same time.
A thread is a basic execution unit which has its own program counter, set of the register
and stack. But it shares the code, data, and file of the process to which it belongs. A process
can have multiple threads simultaneously, and the CPU switches among these threads so fre-
quently making an impression on the user that all threads are running simultaneously.

ET
C

Figure: Multithreading
SV

Benefits of Multithreading
• Multithreading increases the  responsiveness  of system as, if one thread of the
application is not responding, the other would respond in that sense the user would
not have to sit idle.
• Multithreading allows resource sharing as threads belonging to the same process can
share code and data of the process and it allows a process to have multiple threads at
the same time active in same address space.
• Creating a different process is costlier as the system has to allocate different memory
and resources to each process, but creating threads is easy as it does not require
allocating separate memory and resources for threads of the same process.
4.2 Thread Lifecycle
A thread in Java at any point of time exists in any one of the following states. A thread lies
only in one of the shown states at any instant:

CS8392 OBJECT ORIENTED PROGRAMMING 3


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

1) New
2) Runnable
3) Blocked
4) Waiting
5) Timed Waiting
6) Terminated
The following figure represents various states of a thread at any instant of time:

ET
C
SV

Figure: Life Cycle of a thread


1. New Thread: 
• When a new thread is created, it is in the new state.
• The thread has not yet started to run when thread is in this state.
• When a thread lies in the new state, it’s code is yet to be run and hasn’t started to
execute.
2. Runnable State: 
• A thread that is ready to run is moved to runnable state.
• In this state, a thread might actually be running or it might be ready run at any instant
of time.

CS8392 OBJECT ORIENTED PROGRAMMING 4


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

• It is the responsibility of the thread scheduler to give the thread, time to run.
• A multi-threaded program allocates a fixed amount of time to each individual thread.
Each and every thread runs for a short while and then pauses and relinquishes the CPU
to another thread, so that other threads can get a chance to run. When this happens,
all such threads that are ready to run, waiting for the CPU and the currently running
thread lies in runnable state.
3. Blocked/Waiting state:
• When a thread is temporarily inactive, then it’s in one of the following states:
○○ Blocked
○○ Waiting
• For example, when a thread is waiting for I/O to complete, it lies in the blocked state.
It’s the responsibility of the thread scheduler to reactivate and schedule a blocked/
waiting thread.
• A thread in this state cannot continue its execution any further until it is moved to
ET
runnable state. Any thread in these states do not consume any CPU cycle.
• A thread is in the blocked state when it tries to access a protected section of code that
is currently locked by some other thread. When the protected section is unlocked, the
schedule picks one of the threads which is blocked for that section and moves it to
C
the runnable state. A thread is in the waiting state when it waits for another thread on
a condition. When this condition is fulfilled, the scheduler is notified and the waiting
thread is moved to runnable state.
SV

• If a currently running thread is moved to blocked/waiting state, another thread in the


runnable state is scheduled by the thread scheduler to run. It is the responsibility of
thread scheduler to determine which thread to run.
4. Timed Waiting: 
• A thread lies in timed waiting state when it calls a method with a time out parameter.
• A thread lies in this state until the timeout is completed or until a notification is
received.
• For example, when a thread calls sleep or a conditional wait, it is moved to timed
waiting state.
5. Terminated State: 
• A thread terminates because of either of the following reasons:
○○ Because it exits normally. This happens when the code of thread has entirely
executed by the program.

CS8392 OBJECT ORIENTED PROGRAMMING 5


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

○○ Because there occurred some unusual erroneous event, like segmentation fault
or an unhandled exception.
• A thread that lies in terminated state does no longer consumes any cycles of CPU.
Creating Threads
• Threading is a facility to allow multiple tasks to run concurrently within a single
process. Threads are independent, concurrent execution through a program, and each
thread has its own stack.
In Java, There are two ways to create a thread:
1) By extending Thread class.
2) By implementing Runnable interface.
Java Thread Benefits
1. Java Threads are lightweight compared to processes as they take less time and re-
source to create a thread.
ET
2. Threads share their parent process data and code
3. Context switching between threads is usually less expensive than between process-
es.
4. Thread intercommunication is relatively easy than process communication.
C

Thread class:
Thread class provide constructors and methods to create and perform operations on a
SV

thread. Thread class extends Object class and implements Runnable interface.
Commonly used Constructors of Thread class:
• Thread()
• Thread(String name)
• Thread(Runnable r)
• Thread(Runnable r, String name)
Commonly used methods of Thread class:
1. public void run(): is used to perform action for a thread.
2. public void start(): starts the execution of the thread. JVM calls the run() method on
the thread.
3. public void sleep(long miliseconds): Causes the currently executing thread to sleep
(temporarily cease execution) for the specified number of milliseconds.
4. public void join(): waits for a thread to die.

CS8392 OBJECT ORIENTED PROGRAMMING 6


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

5. public void join(long miliseconds):  waits for a thread to die for the specified mili-
seconds.
6. public int getPriority(): returns the priority of the thread.
7. public int setPriority(int priority): changes the priority of the thread.
8. public String getName(): returns the name of the thread.
9. public void setName(String name): changes the name of the thread.
10. public Thread currentThread():  returns the reference of currently executing
thread.
11. public int getId(): returns the id of the thread.
12. public Thread.State getState(): returns the state of the thread.
13. public boolean isAlive(): tests if the thread is alive.
14. public void yield(): causes the currently executing thread object to temporarily pause
ET
and allow other threads to execute.
15. public void suspend(): is used to suspend the thread(depricated).
16. public void resume(): is used to resume the suspended thread(depricated).
C
17. public void stop(): is used to stop the thread(depricated).
18. public boolean isDaemon(): tests if the thread is a daemon thread.
SV

19. public void setDaemon(boolean b): marks the thread as daemon or user thread.
20. public void interrupt(): interrupts the thread.
21. public boolean isInterrupted(): tests if the thread has been interrupted.
22. public static boolean interrupted(): tests if the current thread has been interrupted.
Naming Thread
The Thread class provides methods to change and get the name of a thread. By default,
each thread has a name i.e. thread-0, thread-1 and so on. But we can change the name of the
thread by using setName() method. The syntax of setName() and getName() methods are
given below:
public String getName(): is used to return the name of a thread.
public void setName(String name): is used to change the name of a thread.

CS8392 OBJECT ORIENTED PROGRAMMING 7


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

Extending Thread
The first way to create a thread is to create a new class that extends Thread, and then to
create an instance of that class. The extending class must override the run( ) method, which
is the entry point for the new thread. It must also call start( ) to begin execution of the new
thread.
Sample java program that creates a new thread by extending Thread:
// Create a second thread by extending Thread
class NewThread extends Thread
{
NewThread()
{ // Create a new, second thread
super(“Demo Thread”);
System.out.println(“Child thread: “ + this);
ET
start(); // Start the thread
}
// This is the entry point for the second thread.
C
public void run()
{
SV

try
{
for(int i = 5; i > 0; i--)
{
System.out.println(“Child Thread: “ + i);
Thread.sleep(500);
}
}
catch (InterruptedException e)
{
System.out.println(“Child interrupted.”);
}
System.out.println(“Child thread is exiting”);

CS8392 OBJECT ORIENTED PROGRAMMING 8


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

}
}
public class ExtendThread
{
public static void main(String args[])
{
new NewThread(); // create a new thread
try
{
for(int i = 5; i > 0; i--)
{
System.out.println(“Main Thread: “ + i);
ET
Thread.sleep(1000);
}
}
C
catch (InterruptedException e)
{
SV

System.out.println(“Main thread interrupted.”);


}
System.out.println(“Main thread is exiting.”);
}
}
Sample Output:
(output may vary based on processor speed and task load)
Child thread: Thread[Demo Thread,5,main]
Main Thread: 5
Child Thread: 5
Child Thread: 4
Main Thread: 4
Child Thread: 3

CS8392 OBJECT ORIENTED PROGRAMMING 9


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

Child Thread: 2
Main Thread: 3
Child Thread: 1
Child thread is exiting.
Main Thread: 2
Main Thread: 1
Main thread is exiting.
The child thread is created by instantiating an object of NewThread, which is derived
from Thread. The call to super( ) is inside NewThread. This invokes the following form of
the Thread constructor:
public Thread(String threadName)
Here, threadName specifies the name of the thread.
Implementing Runnable
ET
• The easiest way to create a thread is to create a class that implements the Runnable
interface.
• Runnable abstracts a unit of executable code. We can construct a thread on any object
C
that implements Runnable.
• To implement Runnable, a class need only implement a single method called run( ),
which is declared as:
SV

public void run( )


• Inside run( ), we will define the code that constitutes the new thread. The run( )
can call other methods, use other classes, and declare variables, just like the main
thread can. The only difference is that run( ) establishes the entry point for another,
concurrent thread of execution within the program. This thread will end when run( )
returns.
• After we create a class that implements Runnable, we will instantiate an object of
type Thread from within that class.
• After the new thread is created, it will not start running until we call its start( ) method,
which is declared within Thread. In essence, start( ) executes a call to run( ).
• The start( ) method is shown as:
void start( )

CS8392 OBJECT ORIENTED PROGRAMMING 10


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

Sample java program that creates a new thread by implementing Runnable:


// Create a second thread
class NewThread implements Runnable
{
Thread t;
NewThread()
{
// Create a new, second thread
t = new Thread(this, “Demo Thread”);
System.out.println(“Child thread: “ + t);
t.start(); // Start the thread
}
ET
// This is the entry point for the second thread.
public void run()
{
C
try
{
SV

for(int i = 5; i > 0; i--)


{
System.out.println(“Child Thread: “ + i);
Thread.sleep(500);
}
}
catch (InterruptedException e)
{
System.out.println(“Child interrupted.”);
}
System.out.println(“Child thread is exiting.”);
}
}

CS8392 OBJECT ORIENTED PROGRAMMING 11


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

public class ThreadDemo


{
public static void main(String args[])
{
new NewThread(); // create a new thread
try
{
for(int i = 5; i > 0; i--)
{
System.out.println(“Main Thread: “ + i);
Thread.sleep(1000);
}
ET
}
catch (InterruptedException e)
{
C
System.out.println(“Main thread interrupted.”);
}
SV

System.out.println(“Main thread is exiting.”);


}
}
Inside NewThread’s constructor, a new Thread object is created by the following
statement:
t = new Thread(this, “Demo Thread”);
Passing this as the first argument indicates that we want the new thread to call the run( )
method on this object. Next, start( ) is called, which starts the thread of execution beginning
at the run( ) method. This causes the child thread’s for loop to begin. After calling start( ),
NewThread’s constructor returns to main(). When the main thread resumes, it enters its for
loop. Both threads continue running, sharing the CPU, until their loops finish.

CS8392 OBJECT ORIENTED PROGRAMMING 12


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

Sample Output:
(output may vary based on processor speed and task load)
Child thread: Thread[Demo Thread,5,main]
Main Thread: 5
Child Thread: 5
Child Thread: 4
Main Thread: 4
Child Thread: 3
Child Thread: 2
Main Thread: 3
Child Thread: 1
Child thread is exiting.
ET
Main Thread: 2
Main Thread: 1
Main thread is exiting.
C
In a multithreaded program, often the main thread must be the last thread to finish run-
ning. In fact, for some older JVMs, if the main thread finishes before a child thread has
completed, then the Java run-time system may “hang.” The preceding program ensures that
SV

the main thread finishes last, because the main thread sleeps for 1,000 milliseconds between
iterations, but the child thread sleeps for only 500 milliseconds. This causes the child thread
to terminate earlier than the main thread.
Choosing an Approach
The Thread class defines several methods that can be overridden by a derived class. Of
these methods, the only one that must be overridden is run(). This is, of course, the same
method required when we implement Runnable. Many Java programmers feel that classes
should be extended only when they are being enhanced or modified in some way. So, if we
will not be overriding any of Thread’s other methods, it is probably best simply to implement
Runnable.

CS8392 OBJECT ORIENTED PROGRAMMING 13


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

Creating Multiple Threads


The following program creates three child threads:
// Create multiple threads.
class NewThread implements Runnable
{
String name; // name of thread
Thread t;
NewThread(String threadname)
{
name = threadname;
t = new Thread(this, name);
System.out.println(“New thread: “ + t);
ET
t.start(); // Start the thread
}
// This is the entry point for thread.
C
public void run()
{
SV

try
{
for(int i = 5; i > 0; i--)
{
System.out.println(name + “: “ + i);
Thread.sleep(1000);
}
}
catch (InterruptedException e)
{
System.out.println(name + “Interrupted”);
}
System.out.println(name + “ exiting.”);

CS8392 OBJECT ORIENTED PROGRAMMING 14


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

}
}
public class MultiThreadDemo
{
public static void main(String args[])
{
new NewThread(“One”); // start threads
new NewThread(“Two”);
new NewThread(“Three”);
try
{
// wait for other threads to end
ET
Thread.sleep(10000);
}
catch (InterruptedException e)
C
{
System.out.println(“Main thread Interrupted”);
SV

}
System.out.println(“Main thread exiting.”);
}
}
The output from this program is shown here:
New thread: Thread[One,5,main]
New thread: Thread[Two,5,main]
New thread: Thread[Three,5,main]
One: 5
Two: 5
Three: 5
One: 4
Two: 4

CS8392 OBJECT ORIENTED PROGRAMMING 15


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

Three: 4
One: 3
Three: 3
Two: 3
One: 2
Three: 2
Two: 2
One: 1
Three: 1
Two: 1
One exiting.
Two exiting.
ET
Three exiting.
Main thread exiting.
As we can see, once started, all three child threads share the CPU. The call to sleep(10000)
in main(). This causes the main thread to sleep for ten seconds and ensures that it will finish
C

last.
Using isAlive( ) and join( )
SV

We want the main thread to finish last. In the preceding examples, this is accomplished
by calling sleep( ) within main( ), with a long enough delay to ensure that all child threads
terminate prior to the main thread. However, this is hardly a satisfactory solution, and it also
raises a larger question: How can one thread know when another thread has ended?
Two ways exist to determine whether a thread has finished or not.
• First, we can call isAlive( ) on the thread. This method is defined by Thread.
Syntax:
final boolean isAlive( )
The isAlive( ) method returns true, if the thread upon which it is called is still running. It
returns false, otherwise.
• Second, we can use join() to wait for a thread to finish.
Syntax:
final void join( ) throws InterruptedException

CS8392 OBJECT ORIENTED PROGRAMMING 16


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

This method waits until the thread on which it is called terminates. Its name comes from
the concept of the calling thread waiting until the specified thread joins it.
Sample Java program using join() to wait for threads to finish.
class NewThread implements Runnable
{
String name; // name of thread
Thread t;
NewThread(String threadname)
{
name = threadname;
t = new Thread(this, name);
System.out.println(“New thread: “ + t);
t.start(); // Start the thread
ET
}
// This is the entry point for thread.
public void run()
C

{
SV

try
{
for(int i = 5; i > 0; i--)
{
System.out.println(name + “: “ + i);
Thread.sleep(1000);
}
}
catch (InterruptedException e)
{
System.out.println(name + “ interrupted.”);
}
System.out.println(name + “ is exiting.”);

CS8392 OBJECT ORIENTED PROGRAMMING 17


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

}
}
public class DemoJoin
{
public static void main(String args[])
{
NewThread ob1 = new NewThread(“One”);
NewThread ob2 = new NewThread(“Two”);
NewThread ob3 = new NewThread(“Three”);
System.out.println(“Thread One is alive: “ + ob1.t.isAlive());
System.out.println(“Thread Two is alive: “ + ob2.t.isAlive());
System.out.println(“Thread Three is alive: “ + ob3.t.isAlive());
ET
// wait for threads to finish
try
{
C
System.out.println(“Waiting for threads to finish.”);
ob1.t.join();
SV

ob2.t.join();
ob3.t.join();
}
catch (InterruptedException e)
{
System.out.println(“Main thread Interrupted”);
}
System.out.println(“Thread One is alive: “ + ob1.t.isAlive());
System.out.println(“Thread Two is alive: “ + ob2.t.isAlive());
System.out.println(“Thread Three is alive: “ + ob3.t.isAlive());
System.out.println(“Main thread is exiting.”);
}
}

CS8392 OBJECT ORIENTED PROGRAMMING 18


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

Sample output:
(output may vary based on processor speed and task load)
New thread: Thread[One,5,main]
New thread: Thread[Two,5,main]
One: 5
New thread: Thread[Three,5,main]
Two: 5
Thread One is alive: true
Thread Two is alive: true
Thread Three is alive: true
Waiting for threads to finish.
Three: 5
One: 4
ET
Two: 4
Three: 4
One: 3
C

Two: 3
Three: 3
SV

One: 2
Two: 2
Three: 2
One: 1
Two: 1
Three: 1
One is exiting.
Two is exiting.
Three is exiting.
Thread One is alive: false
Thread Two is alive: false
Thread Three is alive: false
Main thread is exiting.

CS8392 OBJECT ORIENTED PROGRAMMING 19


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

As we can see, after the calls to join( ) return, the threads have stopped executing.
4.3 Synchronization
• Synchronization in java is the capability  to control the access of multiple threads to
any shared resource.
• Java Synchronization is better option where we want to allow only one thread to
access the shared resource.
• When two or more threads need access to a shared resource, they need some way to
ensure that the resource will be used by only one thread at a time. The process by
which this is achieved is called synchronization. Java provides unique, language-
level support for it.
• Key to synchronization is the concept of the monitor (also called a semaphore).
• A monitor is an object that is used as a mutually exclusive lock, or mutex. Only one
thread can own a monitor at a given time. When a thread acquires a lock, it is said
to have entered the monitor. All other threads attempting to enter the locked monitor
ET
will be suspended until the first thread exits the monitor.
• These other threads are said to be waiting for the monitor. A thread that owns a monitor
can reenter the same monitor if it so desires.
• Approaches:
C
○○ Using synchronized Method
○○ Using synchronized Statement
SV

Using Synchronized Methods


Synchronization is easy in Java, because all objects have their own implicit monitor as-
sociated with them.
To enter an object’s monitor, just call a method that has been modified with the synchro-
nized keyword.
While a thread is inside a synchronized method, all other threads that try to call it (or any
other synchronized method) on the same instance have to wait.
To exit the monitor and relinquish control of the object to the next waiting thread, the
owner of the monitor simply returns from the synchronized method.
• To understand the need for synchronization, we will consider a simple example that
does not use it—but should.
• The following program has three simple classes.
• The first one, Callme, has a single method named call( ). The call( ) method takes a
String parameter called msg. This method tries to print the msg string inside of square
brackets. After call( ) prints the opening bracket and the msg string, it calls Thread.

CS8392 OBJECT ORIENTED PROGRAMMING 20


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

sleep(1000), which pauses the current thread for one second.


• The constructor of the next class, Caller, takes a reference to an instance of the Callme
class and a String, which are stored in target and msg, respectively. The constructor
also creates a new thread that will call this object’s run( ) method. The thread is
started immediately. The run( ) method of Caller calls the call( ) method on the target
instance of Callme, passing in the msg string.
• Finally, the Synch class starts by creating a single instance of Callme, and three
instances of Caller, each with a unique message string.
• The same instance of Callme is passed to each Caller.
// This program is not synchronized.
class Callme
{
void call(String msg)
{
ET
System.out.print(“[“ + msg);
try
{
C

Thread.sleep(1000);
}
SV

catch(InterruptedException e)
{
System.out.println(“Interrupted”);
}
System.out.println(“]”);
}
}

class Caller implements Runnable


{
String msg;
Callme target;

CS8392 OBJECT ORIENTED PROGRAMMING 21


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

Thread t;
public Caller(Callme targ, String s)
{
target = targ;
msg = s;
t = new Thread(this);
t.start();
}
public void run()
{
target.call(msg);
}
ET
}

public class Synch


C
{
public static void main(String args[])
SV

{
Callme target = new Callme();
Caller ob1 = new Caller(target, “Hello”);
Caller ob2 = new Caller(target, “Synchronized”);
Caller ob3 = new Caller(target, “World”);
// wait for threads to end
try
{
ob1.t.join();
ob2.t.join();
ob3.t.join();
}
catch(InterruptedException e)

CS8392 OBJECT ORIENTED PROGRAMMING 22


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

{
System.out.println(“Interrupted”);
}
}
}
Sample Output:
Hello[Synchronized[World]
]
]
As we can see, by calling sleep( ), the call( ) method allows execution to switch to another
thread. This results in the mixed-up output of the three message strings.
In this program, nothing exists to stop all three threads from calling the same method, on
the same object, at the same time. This is known as a race condition, because the three threads
ET
are racing each other to complete the method.
This example used sleep( ) to make the effects repeatable and obvious. In most situations,
a race condition is more subtle and less predictable, because we can’t be sure when the con-
text switch will occur. This can cause a program to run right one time and wrong the next.
C

To fix the preceding program, we must serialize access to call(). That is, we must restrict
its access to only one thread at a time. To do this, we simply need to precede call()’s definition
SV

with the keyword synchronized, as shown here:


This prevents other threads from entering call( ) while another thread is using it.
class Callme
{
synchronized void call(String msg)
{
...
Following is the sample java program after synchronized has been added to call( ):
class Callme
{
synchronized void call(String msg)
{
System.out.print(“[“ + msg);

CS8392 OBJECT ORIENTED PROGRAMMING 23


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

try
{
Thread.sleep(1000);
}
catch(InterruptedException e)
{
System.out.println(“Interrupted”);
}
System.out.println(“]”);
}
} ET
class Caller implements Runnable
{
String msg;
C
Callme target;
Thread t;
SV

public Caller(Callme targ, String s)


{
target = targ;
msg = s;
t = new Thread(this);
t.start();
}
public void run()
{
target.call(msg);
}
}

CS8392 OBJECT ORIENTED PROGRAMMING 24


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

public class Synch


{
public static void main(String args[])
{
Callme target = new Callme();
Caller ob1 = new Caller(target, “Hello”);
Caller ob2 = new Caller(target, “Synchronized”);
Caller ob3 = new Caller(target, “World”);
// wait for threads to end
try
{
ob1.t.join();
ET
ob2.t.join();
ob3.t.join();
}
C
catch(InterruptedException e)
{
SV

System.out.println(“Interrupted”);
}
}
}
Output:
[Hello]
[Synchronized]
[World]
Using synchronized Statement
While creating synchronized methods within classes that we create is an easy and effec-
tive means of achieving synchronization, it will not work in all cases. We have to put calls to
the methods defined by the class inside a synchronized block.
Syntax:

CS8392 OBJECT ORIENTED PROGRAMMING 25


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

synchronized(object)
{
// statements to be synchronized
}
Here, object is a reference to the object being synchronized. A synchronized block en-
sures that a call to a method that is a member of object occurs only after the current thread has
successfully entered object’s monitor.
Here is an alternative version of the preceding example, using a synchronized block with-
in the run( ) method:
// This program uses a synchronized block.
class Callme
{
void call(String msg)
ET
{
System.out.print(“[“ + msg);
try
C
{
Thread.sleep(1000);
SV

}
catch (InterruptedException e)
{
System.out.println(“Interrupted”);
}
System.out.println(“]”);
}
}
class Caller implements Runnable
{
String msg;
Callme target;
Thread t;

CS8392 OBJECT ORIENTED PROGRAMMING 26


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

public Caller(Callme targ, String s)


{
target = targ;
msg = s;
t = new Thread(this);
t.start();
}
// synchronize calls to call()
public void run()
{
synchronized(target)
{
ET
// synchronized block
target.call(msg);
}
C
}
}
SV

public class Synch1


{
public static void main(String args[])
{
Callme target = new Callme();
Caller ob1 = new Caller(target, “Hello”);
Caller ob2 = new Caller(target, “Synchronized”);
Caller ob3 = new Caller(target, “World”);
// wait for threads to end
try
{
ob1.t.join();
ob2.t.join();

CS8392 OBJECT ORIENTED PROGRAMMING 27


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

ob3.t.join();
}
catch(InterruptedException e)
{
System.out.println(“Interrupted”);
}
}
}
Here, the call( ) method is not modified by synchronized. Instead, the synchronized state-
ment is used inside Caller’s run( ) method. This causes the same correct output as the preced-
ing example, because each thread waits for the prior one to finish before proceeding.
Sample Output:
[Hello]
ET
[World]
[Synchronized]
Priority of a Thread (Thread Priority):
C
Each thread has a priority. Priorities are represented by a number between 1 and 10. In
most cases, thread schedular schedules the threads according to their priority (known as pre-
SV

emptive scheduling). But it is not guaranteed because it depends on JVM specification that
which scheduling it chooses.
3 constants defined in Thread class:
1. public static int MIN_PRIORITY

2. public static int NORM_PRIORITY

3. public static int MAX_PRIORITY

Default priority of a thread is 5 (NORM_PRIORITY). The value of MIN_PRIORITY is


1 and the value of MAX_PRIORITY is 10.
Sample Java Program:
public class TestMultiPriority1 extends Thread
{
public void run()
{

CS8392 OBJECT ORIENTED PROGRAMMING 28


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

System.out.println(“running thread name is:”+Thread.currentThread().getName());


System.out.println(“running thread priority is:”+Thread.currentThread().getPriority());
}
public static void main(String args[])
{
TestMultiPriority1 m1=new TestMultiPriority1();
TestMultiPriority1 m2=new TestMultiPriority1();
m1.setPriority(Thread.MIN_PRIORITY);
m2.setPriority(Thread.MAX_PRIORITY);
m1.start();
m2.start();
}
ET
}
Output:
running thread name is:Thread-0
C
running thread priority is:10
running thread name is:Thread-1
SV

running thread priority is:1


4.4 Inter-thread communication
Inter-process communication (IPC) is a mechanism that allows the exchange of data be-
tween processes. By providing a user with a set of programming interfaces, IPC helps a
programmer organize the activities among different processes. IPC allows one application to
control another application, thereby enabling data sharing without interference.
IPC enables data communication by allowing processes to use segments, semaphores, and
other methods to share memory and information. IPC facilitates efficient message transfer
between processes. The idea of IPC is based on Task Control Architecture (TCA). It is a flex-
ible technique that can send and receive variable length arrays, data structures, and lists. It
has the capability of using publish/subscribe and client/server data-transfer paradigms while
supporting a wide range of operating systems and languages.
Inter-thread communication or Co-operation is all about allowing synchronized threads to
communicate with each other. Interthread communication is important when you develop an
application where two or more threads exchange some information.

CS8392 OBJECT ORIENTED PROGRAMMING 29


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

Cooperation (Inter-thread communication) is a mechanism in which a thread is paused


running in its critical section and another thread is allowed to enter (or lock) in the same criti-
cal section to be executed. It is implemented by following methods of Object class:
• wait()
• notify()
• notifyAll()
All these methods belong to object class as final so that all classes have them. They must
be used within a synchronized block only.
1) wait() method
Causes current thread to release the lock and wait until either another thread invokes the
notify() method or the notifyAll() method for this object, or a specified amount of time has
elapsed. The current thread must own this object’s monitor, so it must be called from the syn-
chronized method only otherwise it will throw exception.
2) notify() method
ET
Wakes up a single thread that is waiting on this object’s monitor. If any threads are waiting
on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the
discretion of the implementation. Syntax:
public final void notify()
C

3) notifyAll() method
Wakes up all threads that are waiting on this object’s monitor. Syntax:
SV

public final void notifyAll()


// Java program to demonstrate inter-thread communication (wait(), join() and notify()) in
Java
import java.util.Scanner;
public class Thread_Example
{
public static void main(String[] args) throws InterruptedException
{
final Producer_Consumer pc = new Producer_Consumer ();
Thread t1 = new Thread(new Runnable()
{
public void run()
{

CS8392 OBJECT ORIENTED PROGRAMMING 30


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

try
{
pc.producer();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
});
Thread t2 = new Thread(new Runnable()
{
ET
public void run()
{
try
C
{
pc.consumer();
SV

}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
});
t1.start();
t2.start();
t1.join();
t2.join();
}

CS8392 OBJECT ORIENTED PROGRAMMING 31


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

public static class Producer_Consumer


{
public void producer()throws InterruptedException
{
synchronized(this)
{
System.out.println(“producer thread running”);
wait();
System.out.println(“Resumed”);
}
}
public void consumer()throws InterruptedException
ET
{
Thread.sleep(1000);
Scanner ip = new Scanner(System.in);
C
synchronized(this)
{
SV

System.out.println(“Waiting for return key.”);


ip.nextLine();
System.out.println(“Return key pressed”);
notify();
Thread.sleep(1000);
}
}
}
}
The following statements explain how the above producer-Consumer program works.
• The use of synchronized block ensures that only one thread at a time runs. Also since
there is a sleep method just at the beginning of consumer loop, the produce thread
gets a kickstart.

CS8392 OBJECT ORIENTED PROGRAMMING 32


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

• When the wait is called in producer method, it does two things.


1. it releases the lock it holds on PC object.
2. it makes the produce thread to go on a waiting state until all other threads have
terminated, that is it can again acquire a lock on PC object and some other
method wakes it up by invoking notify or notifyAll on the same object.
• Therefore we see that as soon as wait is called, the control transfers to consume thread
and it prints -“Waiting for return key”.
• After we press the return key, consume method invokes notify(). It also does 2 things-
Firstly, unlike wait(), it does not releases the lock on shared resource therefore for
getting the desired result, it is advised to use notify only at the end of your method.
Secondly, it notifies the waiting threads that now they can wake up but only after the
current method terminates.
• As you might have observed that even after notifying, the control does not immediately
passes over to the produce thread. The reason for it being that we have called Thread.
sleep() after notify(). As we already know that the consume thread is holding a lock
ET
on PC object, another thread cannot access it until it has released the lock. Hence only
after the consume thread finishes its sleep time and thereafter terminates by itself, the
produce thread cannot take back the control.
• After a 2 second pause, the program terminates to its completion.
C

• The following program is one more example for interthread communication


SV

class InterThread_Example
{
    public static void main(String arg[])
    {
        final Client c = new Client();
        new Thread()
        {
            public void run()
            {
                c.withdraw(15000);
            }
        }.start();

CS8392 OBJECT ORIENTED PROGRAMMING 33


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

        new Thread()
        {
            public void run()
            {
                c.deposit(10000);
            }
        }.start();
        new Thread()
        {
            public void run()
            {
ET
                c.deposit(10000);
            }
        }.start();    
C

    }
SV

class Client
{
    int amount = 10000;

    synchronized void withdraw(int amount)


    {
        System.out.println(“Available Balance “ + this. amount);
        System.out.println(“withdrawal amount.” + amount);

        if (this.amount < amount)

CS8392 OBJECT ORIENTED PROGRAMMING 34


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

        {
            System.out.println(“Insufficient Balance waiting for deposit.”);
            try
            {
                wait();
            } catch (Exception e)
            {
                System.out.println(“Interruption Occured”);
            }
        }
        this.amount -= amount;
ET
        System.out.println(“Detected amount: “ + amount);
        System.out.println(“Balance amount : “ + this.amount);
    }
C

    synchronized void deposit(int amount)


SV

    {
        System.out.println(“Going to deposit “ + amount);
        this.amount += amount;
        System.out.println(“Available Balance “ + this.amount);
        System.out.println(“Transaction completed.\n”);
        notify();
    }
}
4.5 Daemon thread
Daemon thread is a low priority thread that runs in background to perform tasks such as
garbage collection. Daemon thread in java is a service provider thread that provides services
to the user thread. Its life depend on the mercy of user threads i.e. when all the user threads
dies, JVM terminates this thread automatically.

CS8392 OBJECT ORIENTED PROGRAMMING 35


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

There are many java daemon threads running automatically e.g. gc, finalizer etc.
• It provides services to user threads for background supporting tasks. It has no role in
life than to serve user threads.
• Its life depends on user threads.
• It is a low priority thread.
The command jconsole typed in the command prompt provides information about the
loaded classes, memory usage, running threads etc.
The purpose of the daemon thread is that it provides services to user thread for back-
ground supporting task. If there is no user thread, why should JVM keep running this thread.
That is why JVM terminates the daemon thread if there is no user thread.
Properties:
• They cannot prevent the JVM from exiting when all the user threads finish their
execution.
ET
• JVM terminates itself when all user threads finish their execution
• If JVM finds running daemon thread, it terminates the thread and after that shutdown
itself. JVM does not care whether Daemon thread is running or not.
• It is an utmost low priority thread.
C
Methods for Java Daemon thread by Thread class
The java.lang.Thread class provides two methods for java daemon thread.
SV

Method Description
public void setDaemon(boolean status) used to mark the current thread as daemon
thread or user thread.
public boolean isDaemon() used to check that current is daemon.
// Java program to demonstrate the usage of setDaemon() and isDaemon() method.
public class DaemonThread extends Thread
{
public void run()
{
// Checking whether the thread is Daemon or not
if(Thread.currentThread().isDaemon())
{
System.out.println(“This is Daemon thread”);

CS8392 OBJECT ORIENTED PROGRAMMING 36


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

}
else
{
System.out.println(“This is User thread”);
}
}
public static void main(String[] args)
{
DaemonThread t1 = new DaemonThread();
DaemonThread t2 = new DaemonThread();
DaemonThread t3 = new DaemonThread();
// Setting user thread t1 to Daemon
ET
t1.setDaemon(true);
// starting all the threads
t1.start();
C
t2.start();
t3.start();
SV

// Setting user thread t3 to Daemon


t3.setDaemon(true);
}
}
Output:
This is Daemon thread
This is User thread
This is Daemon thread
// Java program to demonstrate the usage of exception in Daemon() Thread
public class DaemonThread extends Thread
{
public void run()
{

CS8392 OBJECT ORIENTED PROGRAMMING 37


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

System.out.println(“Thread name: “ + Thread.currentThread().getName());


System.out.println(“Check if its DaemonThread: “
+ Thread.currentThread().isDaemon());
}
public static void main(String[] args)
{
DaemonThread t1 = new DaemonThread();
DaemonThread t2 = new DaemonThread();
t1.start();
// Exception as the thread is already started
t1.setDaemon(true);

ET
t2.start();
}
}
C
Output:
Thread name: Thread-0
SV

Check if its DaemonThread: false


Daemon vs User Threads
• Priority:  When the only remaining threads in a process are daemon threads, the
interpreter exits. This makes sense because when only daemon threads remain, there
is no other thread for which a daemon thread can provide a service.
• Usage: Daemon thread is to provide services to user thread for background supporting
task.
The following program is an example for daemon thread.
public class DaemonThread_example extends Thread{  
 public void run(){  
  if(Thread.currentThread().isDaemon()){//checking for daemon thread  
   System.out.println(“daemon thread work”);  
  }  
  else{  

CS8392 OBJECT ORIENTED PROGRAMMING 38


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

  System.out.println(“user thread work”);  
 }  
 }  
 public static void main(String[] args){  
  TestDaemonThread1 t1=new TestDaemonThread1();//creating thread  
  TestDaemonThread1 t2=new TestDaemonThread1();  
  TestDaemonThread1 t3=new TestDaemonThread1();  
  t1.setDaemon(true);//now t1 is daemon thread  
  t1.start();//starting threads  
  t2.start();  
  t3.start();  
 }  
ET
}  
The following program is another example for daemon thread.
class DaemonThread1_example extends Thread{  
C
 public void run(){  
  System.out.println(“Name: “+Thread.currentThread().getName());  
SV

  System.out.println(“Daemon: “+Thread.currentThread().isDaemon());  
 }  
 public static void main(String[] args){  
  TestDaemonThread2 t1=new TestDaemonThread2();  
  TestDaemonThread2 t2=new TestDaemonThread2();  
  t1.start();  
  t1.setDaemon(true);//will throw exception here  
  t2.start();  
 }  
}  

CS8392 OBJECT ORIENTED PROGRAMMING 39


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

4.6 Thread Group in Java


Java provides a convenient way to group multiple threads in a single object. In such way,
we can suspend, resume or interrupt group of threads by a single method call. ThreadGroup
creates a group of threads. It offers a convenient way to manage groups of threads as a unit.
This is particularly valuable in situation in which you want to suspend and resume a number
of related threads.
• The thread group form a tree in which every thread group except the initial thread
group has a parent.
• A thread is allowed to access information about its own thread group but not to access
information about its thread group’s parent thread group or any other thread group.
Constructors of ThreadGroup class
There are only two constructors of ThreadGroup class.
Constructor Description
Thread Group (String name) creates a thread group with given name.
ET
Thread Group (ThreadGroup parent, creates a thread group with given parent group
String name) and name.
The following program is an example for ThreadGroup
public class ThreadGroup_example implements Runnable{  
C

    public void run() {  
          System.out.println(Thread.currentThread().getName());  
SV

    }  
   public static void main(String[] args) {  
      ThreadGroup_example runnable = new ThreadGroup_example();  
          ThreadGroup tg1 = new ThreadGroup(“Parent ThreadGroup”);  
           Thread t1 = new Thread(tg1, runnable,”one”);  
          t1.start();  
          Thread t2 = new Thread(tg1, runnable,”two”);  
          t2.start();  
          Thread t3 = new Thread(tg1, runnable,”three”);  
          t3.start();  

CS8392 OBJECT ORIENTED PROGRAMMING 40


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

          System.out.println(“Thread Group Name: “+tg1.getName());  
         tg1.list();  
      }  
   }  
Sample Output:
one
two
three
Thread Group Name: Parent ThreadGroup
java.lang.ThreadGroup[name=Parent ThreadGroup,maxpri=10]
Thread [one,5,Parent ThreadGroup]
Thread [two,5,Parent ThreadGroup]
ET
Thread [three,5,Parent ThreadGroup]
Methods of ThreadGroup class
There are many methods in ThreadGroup class. A list of important methods are given
below.
C

Method Description
SV

int activeCount() returns no. of threads running in current group.

int activeGroupCount() returns a no. of active group in this thread group.

void destroy() destroys this thread group and all its sub groups.

String getName() returns the name of this group.

ThreadGroup getParent() returns the parent of this group.

void interrupt() interrupts all threads of this group.

void list() prints information of this group to standard console.

CS8392 OBJECT ORIENTED PROGRAMMING 41


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

The following programs explain the threadgroup example.


// Java code illustrating activeCount() method
import java.lang.*;
class NewThread extends Thread
{
NewThread(String threadname, ThreadGroup tgob)
{
super(tgob, threadname);
start();
}
public void run()
{
ET
for (int i = 0; i < 1000; i++)
{
C
try
{
SV

Thread.sleep(10);
}
catch (InterruptedException ex)
{
System.out.println(“Exception encounterted”);
}
}
}
}
public class ThreadGroup_example
{
public static void main(String arg[])
{

CS8392 OBJECT ORIENTED PROGRAMMING 42


SRI VIDYA COLLEGE OF ENGG & TECH Lecture Notes

// creating the thread group


ThreadGroup gfg = new ThreadGroup(“parent thread group”);

NewThread t1 = new NewThread(“one”, gfg);


System.out.println(“Starting one”);
NewThread t2 = new NewThread(“two”, gfg);
System.out.println(“Starting two”);

// checking the number of active thread


System.out.println(“number of active thread: “
+ gfg.activeCount());
}
ET
}
Output:
Starting one
C
Starting two
number of active thread: 2
SV

CS8392 OBJECT ORIENTED PROGRAMMING 43

You might also like