Module 5
Module 5
Email: nanditab.rvitm@rvei.edu.in
syedaayesha.rvitm@rvei.edu.in
roopashrees.rvitm@rvei.edu.in
RV Institute of Technology and Management®
Multitasking
Multitasking is a process of executing multiple tasks simultaneously. We use multitasking
toutilize the CPU. Multitasking can be achieved by two ways:
Each process has its own address in memory i.e. each process allocates separate
memory area.
Process is heavyweight.
Cost of communication between the processes is high.
Switching from one process to another require some time for saving and loading
registers, memory maps, updating lists etc.
Less efficient
An instance of Thread class is just an object, like any other object in java. But a thread of
execution means an individual "lightweight" process that has its own call stack. In java each
thread has its own call stack as shown in Fig. 4.3.
• Often, it must be the last thread to finish execution because it performs various shutdown
actions.
The life cycle of the thread is shown in Fig. 4.4 in java is controlled by JVM. The java thread
states are as follows:
1. New
2. Runnable
3. Running
4. Non-Runnable (Blocked)
5. Terminated
1. New:
The thread is in new state if you create an instance of Thread class but
before the invocation ofstart () method.
2. Runnable:
When we call start () function on Thread object, its state is changed to Runnable.
The control is given to Thread scheduler to finish its execution. Whether to run this
thread instantly or keep it in runnable thread pool before running, depends on the
OS implementation of thread scheduler.
a) Running:
When thread is executing, it’s state is changed to Running. Thread scheduler picks one
of the thread from the runnable thread pool and change its state to Running. Then CPU
starts executingthis thread. A thread can change state to Runnable, Dead or Blocked
from running state depends on time slicing, thread completion of run() method or
waiting for some resources.
b) Non-Runnable (Blocked)
This is the state when the thread is still alive, but is currently not eligible to run. Waiting
− Sometimes, a thread transitions to the waiting state while the thread waits for another
thread to perform a task. A thread transitions back to the runnable state, only when
another thread signals the waiting thread to continue its execution.
c) Terminated
Thread Creation
When the thread starts it schedules the time slots for several sub threads and the JVM scheduler
schedules the time slot to every thread based on round robin technique or priority based.
Method Description
String getName() Retrieves the name of running thread in the current context in String
format
void start() This method will start a new thread of execution by calling run() method
of Thread/runnable object.
void run() This method is the entry point of the thread. Execution of thread starts
from this method.
void sleep(int This method suspends the thread for mentioned time duration in
argument
sleeptime) (sleeptime in ms)
void yield() By invoking this method, the current thread pauses its execution
temporarily and allow other threads to execute.
void join() This method used to queue up a thread in execution. Once called on
thread, current thread will wait till calling thread completes its
execution
run () method introduces a concurrent thread into your program. This thread will end
whenrun() returns.
You must specify the code for your thread inside run() method.
run() method can call other methods, can use other classes and declare variables just
like anyother normal method.
After you create a class that implements Runnable, you will instantiate an object of type
Thread from within that class. Thread defines several constructors. The one that we will use
is shown here:
Syntax :
Thread(Runnable threadOb, String threadName);
In this constructor, threadOb is an instance of a class that implements the Runnable interface.
This defines where execution of the thread will begin. The name of the new thread is
specified by threadName.
{
System.out.println("concurrent thread started running..");
}
}
class MyThreadDemo
{
public static void main( String args[] )
{
MyThread mt = new MyThread();
Thread t = new Thread(mt); t.start();
}
package applet1;
import java.io.*;
import java.util.*;
{
System.out.println(i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println( "Interrupted");
}
System.out.println(" exiting.");
}
}
class B implements Runnable {
public void
run() {try {
} catch (InterruptedException e) {
System.out.println("Interrupted")
;
System.out.println(" exiting.");
}
}
class multithread {
Output: 5
15
14
4
13
3
12
2
11
1
exiting
exiting
Notice the call to sleep (10000) in main (). This causes threads B and A to sleep for ten
secondsand ensures that it will finish last.
Note: Write a java application program for generating 3 threads to perform thefollowing
operations.
i)Reading n numbers ii) Printing prime numbers iii) Computing average of nnumbers
The isAlive() method returns true if the thread upon which it is called is still running
otherwise itreturns false.
{
System.out.println("r1 ");
try {
Thread.sleep(500);
}
catch(InterruptedException ie)
{ }System.out.println("r2 ");
}
public static void main(String[] args)
{
MyThread t1=new MyThread();
MyThread t2=new MyThread();
t1.start();
t2.start();
System.out.println(t1.isAlive());
System.out.println(t2.isAlive());
}
Output:
r1
true
true
r1
r2
r2
But, join() method is used more commonly than isAlive(). This method waits until the thread
onwhich it is called terminates
Using join() method, we tell our thread to wait until the specified thread completes its
execution. There are overloaded versions of join() method, which allows us to specify time for
which you want to wait for the specified thread to terminate
{
public void run()
{
System.out.println("r1 ");
try {
Thread.sleep(500);
}catch(InterruptedException ie){ }
System.out.println("r2 ");
}
public static void main(String[] args)
{
MyThread t1=new MyThread();
MyThread t2=new MyThread();
t1.start();
try{
t1.join(); //Waiting for t1 to finish
}catch(InterruptedException ie){}
t2.start();
}
}
Output:
r1
r2
r1
r2
In this above program join() method on thread t1 ensures that t1 finishes it process before
threadt2 starts.
t1.join(1500);
Synchronization
At times when more than one thread try to access a shared resource, we need to ensure that
resource will be used by only one thread at a time. The process by which this is achieved is
called synchronization. The synchronization keyword in java creates a block of code referred
toas critical section.
General Syntax :
synchronized (object)
//statement to be synchronized
}
class Table{
void display(int n)
{
synchronized(this)
{
for(int i=1;i<=5;i++)
{
System.out.println(n*i);
try{
Thread.sleep(400);
}
catch(Exception e){
System.out.println(e);
}
}
}
}//end of the method
}
B(Table t)
{
this.t=t;
}
public void run(){
t.display(100);
}
}
A t1=new A(obj);
B t2=new B(obj);
t1.start();
t2.start();
}
}
Output:
5
10
15
20
25
100
200
300
400
500
class Table{
synchronized void display(int n)
{
for(int i=1;i<=5;i++)
{
System.out.println(n*i);
try{
Thread.sleep(400);
}
catch(Exception e){
System.out.println(e);
}
}
}
}//end of the method
{
Table t;
A(Table t)
{
this.t=t;
}
public void run(){
t.display(5);
}
}
t.display(100);
}
}
20
25
100
200
300
400
At the same time, the consumer is consuming the data (i.e. removing it from the
buffer), one piece at a time.
Solution:
This problem can be implemented or solved by different ways in Java, classical way is
using waitand notify method to communicate between Producer and Consumer thread and
blocking each of themon individual condition like full queue and empty queue.
wait ( ) tells the calling thread to give up the monitor and go to sleep until some other
threadenters the same monitor and calls notify( ) or notifyAll( ).
public class
ProducerConsumerTest
{ public static void
main(String[] args) {
Myclass c = new Myclass();
Producer p1 = new Producer(c, 1);
Consumer c1 = new Consumer(c, 1);
p1.start();
c1.start();
}
}
class Myclass {
private int contents;
private boolean available = false;
}
available = false;
notifyAll();
return contents;
}
public synchronized void put(int value) {
while (available == true) {
try {
wait();
} catch (InterruptedException e) { }
}
contents = value;
available = true;
notifyAll();
}
}
class Consumer extends Thread {
private Myclass Myclass;
private int number;
this.number = number;
}
public void run() {
int value = 0;
}
}
}
this.number = number;
}
public void run() {
Output:
Producer #1 put: 0
Consumer #1 got: 0
Producer #1 put: 1
Consumer #1 got: 1
Producer #1 put: 2
Consumer #1 got: 2
Producer #1 put: 3
Consumer #1 got: 3
Producer #1 put: 4
Consumer #1 got: 4
Producer #1 put: 5
Consumer #1 got: 5
Producer #1 put: 6
Consumer #1 got: 6
Producer #1 put: 7
Consumer #1 got: 7
Producer #1 put: 8
Consumer #1 got: 8
Producer #1 put: 9
Consumer #1 got: 9
Problem Statement:
There is a buffer of n slots and each slot is capable of storing one unit of data. There are
two processes running, namely, producer and consumer, which are operating on the buffer.
A producer tries to insert data into an empty slot of the buffer. A consumer tries to remove
data from a filled slot in the buffer. As you might have guessed by now, those two processes
won’t produce the expected output if they are being executed concurrently.
There needs to be a way to make the producer and consumer work in an independent manner.
import java.io.*;
import java.util.*;
class Buffer
{
private final int MaxBuffSize;
private int[] store;
private int BufferStart, BufferEnd, BufferSize;
public Buffer(int size)
{
MaxBuffSize = size;
BufferEnd = -1;
BufferStart = 0;
BufferSize = 0;
store = new int[MaxBuffSize];
}
public synchronized void insert(int ch)
{
try
{
}
}
class boundedbuffer {
public static void main(String[] args) {
System.out.println("program starting");
Buffer buffer = new Buffer(5); // buffer has size 5
Producer prod = new Producer(buffer); Consumer
cons = new Consumer(buffer);
prod.start();
cons.interrupt();
try {
prod.join();
cons.interrupt();
} catch (InterruptedException e) {}
System.out.println("End of Program");
}
}
Output:
0
1
2
3
4
5
6
End of Program
Problem Statement:
There is a shared resource which should be accessed by multiple processes. There are two
types of processes in this context. They are reader and writer. Any number of readers can
read from the shared resource simultaneously, but only one writer can write to the shared
resource. When awriter is writing data to the resource, no other process can access the
resource. A writer cannot write to the resource if there are non-zero number of readers
accessing the resource.
Solution:
From the above problem statement, it is evident that readers have higher priority than writer.
If a writer wants to write to the resource, it must wait until there are no readers currently
accessing that resource
Interthread Communication
o wait()
o notify()
o notifyAll()
1) wait() method
The 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 synchronized
method only otherwise it will throw exception.
2) notify() method
The notify() method 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.
III- Semester, Object Oriented Programming with JAVA Page 25 of 29
(BCS306A)
RV Institute of Technology and Management®
Syntax:
3) notifyAll() method
Syntax:
Why wait(), notify() and notifyAll() methods are defined in Object class not Thread class?
wait() sleep()
The wait() method releases the lock. The sleep() method doesn't release the lock.
It should be notified by notify() or notifyAll() methods After the specified amount of time, sleep is completed.
Output:
going to withdraw...
Less balance; waiting for deposit...
going to deposit...
deposit completed...
withdraw completed
Syntax
public final void suspend()
Example
1. public class JavaSuspendExp extends Thread
2. {
3. public void run()
4. {
5. for(int i=1; i<5; i++)
6. {
7. try
8. {
9. // thread to sleep for 500 milliseconds
10. sleep(500);
III- Semester, Object Oriented Programming with JAVA Page 28 of 29
(BCS306A)
RV Institute of Technology and Management®
11. System.out.println(Thread.currentThread().getName());
12. }catch(InterruptedException e){System.out.println(e);}
13. System.out.println(i);
14. }
15. }
16. public static void main(String args[])
17. {
18. // creating three threads
19. JavaSuspendExp t1=new JavaSuspendExp ();
20. JavaSuspendExp t2=new JavaSuspendExp ();
21. JavaSuspendExp t3=new JavaSuspendExp ();
22. // call run() method
23. t1.start();
24. t2.start();
25. // suspend t2 thread
26. t2.suspend();
27. // call run() method
28. t3.start();
29. }
30. }
Output
Thread-0
1
Thread-2
1
Thread-0
2
Thread-2
2
Thread-0
3
Thread-2
3
Thread-0
4
Thread-2
4
Syntax
1. public final void stop()
2. public final void stop(Throwable obj)
3. public class JavaStopExp extends Thread
4. {
5. public void run()
6. {
7. for(int i=1; i<5; i++)
8. {
9. try
10. {
11. // thread to sleep for 500 milliseconds
12. sleep(500);
13. System.out.println(Thread.currentThread().getName());
14. }catch(InterruptedException e){System.out.println(e);}
15. System.out.println(i);
16. }
17. }
18. public static void main(String args[])
19. {
20. // creating three threads
21. JavaStopExp t1=new JavaStopExp ();
22. JavaStopExp t2=new JavaStopExp ();
23. JavaStopExp t3=new JavaStopExp ();
24. // call run() method
25. t1.start();
26. t2.start();
27. // stop t3 thread
28. t3.stop();
29. System.out.println("Thread t3 is stopped");
30. }
31. }
Syntax
1. public final void resume()
2. public class JavaResumeExp extends Thread
3. {
4. public void run()
5. {
6. for(int i=1; i<5; i++)
7. {
8. try
9. {
10. // thread to sleep for 500 milliseconds
11. sleep(500);
12. System.out.println(Thread.currentThread().getName());
13. }catch(InterruptedException e){System.out.println(e);}
14. System.out.println(i);
15. }
16. }
17. public static void main(String args[])
18. {
19. // creating three threads
20. JavaResumeExp t1=new JavaResumeExp ();
21. JavaResumeExp t2=new JavaResumeExp ();
22. JavaResumeExp t3=new JavaResumeExp ();
23. // call run() method
24. t1.start();
25. t2.start();
26. t2.suspend(); // suspend t2 thread
27. // call run() method
28. t3.start();
29. t2.resume(); // resume t2 thread
30. }
31. }
A thread is a program in execution created to perform a specific task. Life cycle of a Java thread
starts with its birth and ends on its death.
The start() method of the Thread class is used to initiate the execution of a thread and it goes into
runnable state and the sleep() and wait() methods of the Thread class sends the thread into non
runnable state.
After non runnable state, thread again comes into runnable state and starts its execution. The run()
method of thread is very much important. After executing the run() method, the lifecycle of thread
is completed.
To work with threads in a program, it is important to identify thread state. The following
figure shows thread states in Java thread life cycle.
1. New
2. Runnable
3. Running
4. Blocked (Non-runnable state)
III- Semester, Object Oriented Programming with JAVA Page 32 of 29
(BCS306A)
RV Institute of Technology and Management®
5. Dead
In simpler terms, Thread object is created but it cannot execute any program statement because it
is not in an execution state of the thread. Only start() method can be called on a new thread;
otherwise, an IllegalThreadStateException will be thrown.
Runnable State
The second phase of a new-born thread is the execution phase. When the start() method is called
on a the new instance of a thread, it enters into a runnable state.
In the runnable state, thread is ready for execution and is waiting for availability of the processor
(CPU time). There are many threads that are ready for execution, they all are waiting in a queue
(line).
If all threads have equal priority, a time slot is assigned for each thread execution on the basis of
first-come, first-serve manner by CPU. The process of allocating time to threads is known as time
slicing. A thread can come into runnable state from running, waiting, or new states.
Running State
Running means Processor (CPU) has allocated time slot to thread for its execution. When thread
scheduler selects a thread from the runnable state for execution, it goes into running state. Look at
the above figure.
In running state, processor gives its time to the thread for execution and executes its run method. It
is the state where thread performs its actual functions. A thread can come into running state only
from runnable state.
A running thread may give up its control in any one of the following situations and can enter into
the blocked state.
1. When sleep() method is invoked on a thread to sleep for specified time period, the thread is out of
queue during this time period. The thread again reenters into the runnable state as soon as this time
period is elapsed.
2. When a thread is suspended using suspend() method for some time in order to satisfy some
conditions. A suspended thread can be revived by using resume() method.
3. When wait() method is called on a thread to wait for some time. The thread in wait state can be run
again using notify() or notifyAll() method.
Blocked State
III- Semester, Object Oriented Programming with JAVA Page 33 of 29
(BCS306A)
RV Institute of Technology and Management®
A thread is considered to be in the blocked state when it is suspended, sleeping, or waiting for
some time in order to satisfy some condition.
Dead State
A thread dies or moves into dead state automatically when its run() method completes the
execution of statements. That is, a thread is terminated or dead when a thread comes out of run()
method. A thread can also be dead when the stop() method is called.
During the life cycle of thread in Java, a thread moves from one state to another state in a variety
of ways. This is because in multithreading environment, when multiple threads are executing, only
one thread can use CPU at a time.
All other threads live in some other states, either waiting for their turn on CPU or waiting for
satisfying some conditions. Therefore, a thread is always in any of the five states.
ENUMERATION
Enumeration is a list of named constants, and these Java enumerations define a class type. By
making enumerations into classes, the concept of enumeration is greatly expanded in Java. In the
simplest form, Java enumerations appear similar to enumerations in other languages, except that
the classes play a significant role in this concept. Enumeration is used using the keyword enum.
For example: here are the lists of various types of programming languages declared using an
enumeration.
The Enum in Java is a data type which contains a fixed set of constants.
It can be used for days of the week (SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, and SATURDAY) , directions (NORTH, SOUTH, EAST, and WEST),
season (SPRING, SUMMER, WINTER, and AUTUMN or FALL), colors (RED, YELLOW,
BLUE, GREEN, WHITE, and BLACK) etc. According to the Java naming conventions, we
should have all constants in capital letters. So, we have enum constants in capital letters.
Java Enums can be thought of as classes which have a fixed set of constants (a variable that does
not change). The Java enum constants are static and final implicitly. It is available since JDK 1.5.
Enums are used to create our own data type like classes. The enum data type (also known as
Enumerated Data Type) is used to define an enum in Java. Unlike C/C++, enum in Java is
more powerful. Here, we can define an enum either inside the class or outside the class.
Java Enum internally inherits the Enum class, so it cannot inherit any other class, but it can
implement many interfaces. We can have fields, constructors, methods, and main methods in Java
enum.
The Java compiler internally adds the values() method when it creates an enum. The values()
method returns an array containing all the values of the enum.
The Java compiler internally adds the valueOf() method when it creates an enum. The
valueOf() method returns the value of given constant enum.
The Java compiler internally adds the ordinal() method when it creates an enum. The
ordinal() method returns the index of the enum value.
Defining Java Enum
The enum can be defined within or outside the class because it is similar to a class. The semicolon
(;) at the end of the enum constants are optional. For example:
or
Output:
WINTER
SPRING
SUMMER
FALL
Let us see another example of Java enum where we are using value(), valueOf(), and ordinal()
methods of Java enum.
1. class EnumExample1{
2. //defining enum within class
3. public enum Season { WINTER, SPRING, SUMMER, FALL }
4. //creating the main method
5. public static void main(String[] args) {
6. //printing all enum
7. for (Season s : Season.values()){
8. System.out.println(s);
9. }
10. System.out.println("Value of WINTER is: "+Season.valueOf("WINTER"));
11. System.out.println("Index of WINTER is: "+Season.valueOf("WINTER").ordinal());
12. System.out.println("Index of SUMMER is: "+Season.valueOf("SUMMER").ordinal());
13.
14. }}
15. Output:
WINTER
SPRING
SUMMER
FALL
Value of WINTER is: WINTER
Index of WINTER is: 0
Index of SUMMER is: 2
Output:
WINTER
Java Enum Example: Defined inside class
1. class EnumExample3{
2. enum Season { WINTER, SPRING, SUMMER, FALL; }//semicolon(;) is optional here
3. public static void main(String[] args) {
4. Season s=Season.WINTER;//enum type is required to access WINTER
5. System.out.println(s);
6. }}
Output:
WINTER
Java Enum Example: main method inside Enum
If you put main() method inside the enum, you can run the enum directly
1. enum Season {
2. WINTER, SPRING, SUMMER, FALL;
3. public static void main(String[] args) {
4. Season s=Season.WINTER;
5. System.out.println(s);
6. }
7. }
Output:
WINTER
The wrapper class in Java provides the mechanism to convert primitive into object and object
into primitive.
Since J2SE 5.0, autoboxing and unboxing feature convert primitives into objects and objects into
primitives automatically. The automatic conversion of primitive into an object is known as
autoboxing and vice-versa unboxing.
Java is an object-oriented programming language, so we need to deal with objects many times like
in Collections, Serialization, Synchronization, etc. Let us see the different scenarios, where we
need to use the wrapper classes.
o Change the value in Method: Java supports only call by value. So, if we pass a primitive
value, it will not change the original value. But, if we convert the primitive value in an
object, it will change the original value.
o Serialization: We need to convert the objects into streams to perform the serialization. If
we have a primitive value, we can convert it in objects through the wrapper classes.
o Synchronization: Java synchronization works with objects in Multithreading.
o java.util package: The java.util package provides the utility classes to deal with objects.
boolean Boolean
char Character
byte Byte
short Short
int Integer
long Long
float Float
double Double
o Collection Framework: Java collection framework works with objects only. All classes of
the collection framework (ArrayList, LinkedList, Vector, HashSet, LinkedHashSet,
TreeSet, PriorityQueue, ArrayDeque, etc.) deal with objects only.
The eight classes of the java.lang package are known as wrapper classes in Java. The list
of eight wrapper classes are given below:
Autoboxing
The automatic conversion of primitive data type into its corresponding wrapper class is
known as autoboxing, for example, byte to Byte, char to Character, int to Integer, long to
Long, float to Float, boolean to Boolean, double to Double, and short to Short.
Since Java 5, we do not need to use the valueOf() method of wrapper classes to convert
the primitive into objects.
Output:
20 20 20
Unboxing
The automatic conversion of wrapper type into its corresponding primitive type is known
as unboxing. It is the reverse process of autoboxing. Since Java 5, we do not need to use
the intValue() method of wrapper classes to convert the wrapper type into primitives.
Output:
3 3 3
Output:
Short object: 20
Integer object: 30
Long object: 40
Float object: 50.0
Double object: 60.0
Character object: a
Boolean object: true
---Printing primitive values---
byte value: 10
short value: 20
int value: 30
long value: 40
float value: 50.0
double value: 60.0
char value: a
boolean value: true