OOPS With Java BCS306A Mod 5 Notes For Exam @vtunetwork
OOPS With Java BCS306A Mod 5 Notes For Exam @vtunetwork
Lecture Notes
Name Of the Programme B.E - CSE
Scheme 2022
MODULE V
Multithreaded Programming: The Java Thread Model, The Main Thread, Creating a Thread, Creating
Multiple Threads, Using isAlive() and join(), Thread Priorities, Synchronization, Interthread
Communication, Suspending, Resuming, and Stopping Threads, Obtaining a Thread’s State.
Enumerations, Type Wrappers and Autoboxing: Enumerations (Enumeration Fundamentals, The values()
and valueOf() Methods), Type Wrappers (Character, Boolean, The Numeric Type Wrappers), Autoboxing
(Autoboxing and Methods, Autoboxing/Unboxing Occurs in Expressions, Autoboxing/Unboxing
Boolean and Character Values).
Thread:
A thread is a single sequential (separate) flow of control within program. Sometimes, it is called an
execution context or light weight process.
Multithreading
Multithreading is a conceptual programming concept where a program (process) is divided into two or
more subprograms (process), which can be implemented at the same time in parallel. A multithreaded
program contains two or more parts that can run concurrently. Each part of such a program is called a
thread, and each thread defines a separate path of execution.
Life Cycle of Thread: A thread can be in any of the five following states.
1. Newborn State:
When a thread object is created a new thread is born and said to be in Newborn state.
2. Runnable State:
If a thread is in this state it means that the thread is ready for execution and waiting for the availability of
the processor. If all threads in queue are of same priority, then they are given time slots for execution in
round robin fashion.
3. Running State:
It means that the processor has given its time to the thread for execution.
A thread keeps running until the following conditions occurs.
(a) Thread gives up its control on its own and it can happen in the following situations
i. A thread gets suspended using suspend() method which can only be revived with resume() method.
ii. A thread is made to sleep for a specified period using sleep(time) method, where time is in milliseconds.
iii. A thread is made to wait for some event to occur using wait () method. In this case a thread can be
scheduled to run again using notify () method.
(b) A thread is pre-empted by a higher priority thread
4. Blocked State:
If a thread is prevented from entering into runnable state and subsequently running state, then a thread is
said to be in Blocked state.
5. Dead State:
A runnable thread enters the Dead or terminated state when it completes its task.
class CurrentThreadDemo
{
public static void main(String args[])
{
Thread t = Thread.currentThread();
Prof K RADHIKA, Dept of CSE SSCE, Anekal
REGULATION 2022 SCHEME. OOP WITH JAVA - BCS306A
Thread.sleep(5000);
}
}
catch (InterruptedException e)
{
System.out.println("Main interrupted");
}
System.out.println("Exiting Main Thread");
}
}
Output:
Main Thread5
Child Thread5
Child Thread4
Child Thread3
Child Thread2
Child Thread1
Main Thread4
Exiting Child Thread
Main Thread3
Main Thread2
Main Thread1
Exiting Main Thread
2. Extending Thread Class
The second 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.
Example:
public class ThreadSample extends Thread
{
public void run()
{
try
{
for (int i = 5; i > 0; i--)
{
System.out.println("Child Thread" + i);
Thread.sleep(1000);
}
}
catch (InterruptedException e)
{
System.out.println("Child interrupted");
}
System.out.println("Exiting Child Thread");
}
}
public class MainThread
{
public static void main(String[] arg)
{
ThreadSample d = new ThreadSample();
d.start();
try
{
for (int i = 5; i > 0; i--)
{
System.out.println("Main Thread" + i);
Thread.sleep(5000);
}
}
catch (InterruptedException e)
{
System.out.println("Main interrupted");
}
System.out.println("Exiting Main Thread");
}
}
Output:
Child Thread5
Main Thread5
Child Thread4
Child Thread3
Child Thread2
Child Thread1
Main Thread4
Exiting Child Thread
Main Thread3
Main Thread2
Main Thread1
Exiting Main Thread
Creating Multiple Threads
}
// This is the entry point for thread.
public void run()
{
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.");
}
}
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
Thread.sleep(10000);
}
catch (InterruptedException e)
{
System.out.println("Main thread Interrupted");
}
System.out.println("Main thread exiting.");
}
}
Output:
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
Three: 4
One: 3
Three: 3
Two: 3
One: 2
Three: 2
Two: 2
One: 1
Three: 1
Two: 1
One exiting.
Two exiting.
Three exiting.
Main thread exiting.
Using isAlive() and join()
Sometimes one thread needs to know when other thread is terminating. In java, isAlive() and join() are
two different methods that are used to check whether a thread has finished its execution or not.
The isAlive() method returns true if the thread upon which it is called is still running otherwise it returns
false.
Syntax: final boolean isAlive()
join() method is used more commonly than isAlive(). This method waits until the thread on which it is
called terminates.
Syntax: final void join() throws InterruptedException
schedular schedules the threads according to their priority (known as preemptive scheduling). But it is not
guaranteed because it depends on JVM specification that which scheduling it chooses.
3 constants defined in Thread class:
public static int MIN_PRIORITY
public static int NORM_PRIORITY
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.
Example :
public class MyThread1 extends Thread
{
MyThread1(String s)
{
super(s);
start();
}
public void run()
{
for(int i=0;i<5;i++)
{
Thread cur=Thread.currentThread();
cur.setPriority(Thread.MAX_PRIORITY);
int p=cur.getPriority();
System.out.println("Thread Name"+Thread.currentThread().getName());
System.out.println("Thread Priority"+cur);
}
}
}
class MyThread2 extends Thread
{
MyThread2(String s)
{
super(s);
start();
}
public void run()
{
for(int i=0;i<5;i++)
{
Thread cur=Thread.currentThread();
cur.setPriority(Thread.MIN_PRIORITY);
System.out.println(cur.getPriority());
int p=cur.getPriority();
System.out.println("Thread Name"+Thread.currentThread().getName());
System.out.println("Thread Priority"+cur);
}
}
}
public class ThreadPriority
{
public static void main(String[] args)
{
MyThread1 m1=new MyThread1("MyThread1");
MyThread2 m2=new MyThread2("MyThread2");
}
}
Output:
1
Thread NameMyThread2
Thread NameMyThread1
Thread PriorityThread[MyThread2,1,main]
1
Thread NameMyThread2
Thread PriorityThread[MyThread2,1,main]
1
Thread NameMyThread2
Thread PriorityThread[MyThread1,10,main]
Thread NameMyThread1
Thread PriorityThread[MyThread1,10,main]
Thread NameMyThread1
Thread PriorityThread[MyThread2,1,main]
1Thread NameMyThread2
Thread PriorityThread[MyThread1,10,main]
Thread NameMyThread1Thread PriorityThread[MyThread2,1,main]
1Thread PriorityThread[MyThread1,10,main]
Thread NameMyThread2
Thread NameMyThread1
Thread PriorityThread[MyThread1,10,main]
Thread PriorityThread[MyThread2,1,main]
Synchronizing Threads
o Synchronization in Java is the capability to control the access of multiple threads to any shared
resource.
o Java Synchronization is better option where we want to allow only one thread to access the shared
resource
Why use Synchronization
The synchronization is mainly used
o To prevent thread interference.
o To prevent consistency problem.
Thread Synchronization
• Synchronized method.
• Synchronized block.
Synchronized method
}
Output:
[Hello]
[Synchronized]
[World]
Synchronized block
• Synchronized block can be used to perform synchronization on any specific resource of the
method.
• Suppose you have 50 lines of code in your method, but you want to synchronize only 5 lines, you
can use synchronized block.
• If you put all the codes of the method in the synchronized block, it will work same as the
synchronized method.
Example of synchronized block
class Table
{
void printTable(int n)
{
synchronized(this)
{//synchronized block
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
}
}
class MyThread2 extends Thread
{
Table t;
MyThread2(Table t)
{
this.t=t;
}
public void run()
{
t.printTable(100);
}
}
class TestSynchronizedBlock1
{
public static void main(String args[])
{
Table obj = new Table();//only one object
MyThread1 t1=new MyThread1(obj);
MyThread2 t2=new MyThread2(obj);
t1.start();
t2.start();
}
}
Output:
5 10 15 20 25
100 200
300 400 500
Inter-thread communication
Inter-thread communication is all about allowing synchronized threads to communicate with each other.
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 critical section to be executed. It is implemented
by following methods of Object class:
• wait()
• notify()
• notifyAll()
wait()
tells calling thread to give up monitor and go to sleep until some other thread enters the same monitor and
call notify.
notify()
wakes up a thread that called wait() on same object.
notifyAll()
wakes up all the thread that called wait() on same object.
These methods are declared within Object, as shown here:
final void wait( ) throws InterruptedException
}}
class Producer implements Runnable {
Q q;
Producer(Q q) {
this.q = q;
new Thread(this, "Producer").start();
}
public void run() {
int i = 0;
while(true) {
q.put(i++);
}}
}
class Consumer implements Runnable {
Q q;
Consumer(Q q) {
this.q = q;
new Thread(this, "Consumer").start();
}
public void run() {
while(true) {
q.get(); }
}}
class PCFixed {
public static void main(String args[]) {
Q q = new Q();
new Producer(q);
new Consumer(q);
System.out.println("Press Control-C to stop.");
}
}
Output:
Put: 1
Got: 1
Put: 2
Got: 2
Put: 3
Got: 3
Put: 4
Got: 4
Put: 5
Got: 5
Thread.sleep(500);
thread.suspend();
System.out.println("Thread going to sleep for 5 seconds");
Thread.sleep(5000);
System.out.println("Thread Resumed");
thread.resume();
}
}
Output:
Thread 10 is running
Thread going to sleep for 5 seconds
Thread Resumed
Write a program to illustrate creation of threads using runnable class. (start method start each of the newly created
thread. Inside the run method there is sleep() for suspend the thread for 500 milliseconds).
AIM: To develop a JAVA program to illustrate creation of threads using runnable class.
Output:
14 Count: 1
15 Count: 1
15 Count: 2
14 Count: 2
15 Count: 3
14 Count: 3
14 Count: 4
15 Count: 4
15 Count: 5
14 Count: 5
RESULT: Thus, the program to illustrate creation of threads using runnable class has been executed
successfully and the output was verified.
Develop a program to create a class MyThread in this class a constructor, call the base class constructor,
using super and start the thread. The run method of the class starts after this. It can be observed that both
main thread and created child thread are executed concurrently.
AIM: To develop a JAVA program to illustrate creation of threads, call the base class constructor,
using super and start the thread.
Output:
Main Thread Count: 1
Thread ChildThread1 Count: 1
Prof K RADHIKA, Dept of CSE SSCE, Anekal
REGULATION 2022 SCHEME. OOP WITH JAVA - BCS306A
RESULT: Thus, the program to illustrate creation of threads, call the base class constructor, using
super and start the thread has been executed successfully and the output was verified.
Enumerations
An enumeration is a list of named constants. In Java, enumerations define class types. That is, in Java,
enumerations can have constructors, methods and variables. An enumeration is created using the keyword
enum. Following is an example –
enum Person {
Married, Unmarried, Divorced, Widowed
}
The identifiers like Married, Unmarried etc. are called as enumeration Constants. Each such constant is
implicitly considered as a public static final member of Person.
After defining enumeration, we can create a variable of that type. Though enumeration is a class type, we
need not use new keyword for variable creation, rather we can declare it just like any primitive data type.
For example,
Person p= Person.Married;
We can use == operator for comparing two enumeration variables. They can be used in switch-case also.
Printing an enumeration variable will print the constant name. That is,
System.out.println(p); // prints as Married
Consider the following program to illustrate working of enumerations:
enum Season {
Winter, Spring, Summer,Fall
}
class EnumDemo
{
public static void main(String args[])
{
Season p1;
p1=Season.Winter;
System.out.println("Value of p1 :" + p1);
Person p2= Season.Spring;
if(p1==p2)
System.out.println("p1 and p2 are same");
else
System.out.println("p1 and p2 are different");
switch(p1)
{
case Winter: System.out.println("p1 is Winter");
break;
case Spring: System.out.println("p1 is Spring");
break;
case Summer: System.out.println("p1 is Summer");
break;
case Fall: System.out.println("p1 is Fall");
break;
}
}
}
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
Java enumeration is a class type. That is, we can write constructors, add instance variables and methods,
and even implement interfaces. It is important to understand that each enumeration constant is an object
of its enumeration type. Thus, when you define a constructor for an enum, the constructor is called when
each enumeration constant is created. Also, each enumeration constant has its own copy of any instance
variables defined by the enumeration.
class EnumExample4
{
enum Season
{
WINTER(5), SPRING(10), SUMMER(15), FALL(20);
WINTER value is 5
SPRING value is 10
SUMMER value is 15
FALL value is 20
All enumerations automatically inherited from java.lang.Enum. This class defines several methods that are
available for use by all enumerations. We can obtain a value that indicates an enumeration constant’s position
in the list of constants. This is called its ordinal value, and it is retrieved by calling the ordinal() method,
shown here:
It returns the ordinal value of the invoking constant. Ordinal values begin at zero. We can compare the
ordinal value of two constants of the same enumeration by using the compareTo() method. It has this general
form:
Here, e1 and e2 should be the enumeration constants belonging to same enum type. If the ordinal value of e1
is less than that of e2, then compareTo() will return a negative value. If two ordinal values are equal, the
method will return zero. Otherwise, it will return a positive number.
We can compare for equality an enumeration constant with any other object by using equals( ), which
overrides the equals( ) method defined by Object.
enum Apple {
class EnumDemo4 {
System.out.println("Here are all apple constants" + " and their ordinal values: ");
for(Apple a : Apple.values())
ap = Apple.RedDel;
ap2 = Apple.GoldenDel;
ap3 = Apple.RedDel;
System.out.println();
if(ap.compareTo(ap2) < 0)
if(ap.compareTo(ap2) > 0)
if(ap.compareTo(ap3) == 0)
System.out.println();
if(ap.equals(ap2))
System.out.println("Error!");
if(ap.equals(ap3))
if(ap == ap3)
Output:
Jonathan 0
GoldenDel 1
RedDel 2
Winesap 3
Cortland 4
RedDel == RedDel
TypeWrappers
Java uses primitive types (also called simple types), such as int or double, to hold the basic data types
supported by the language. Primitive types, rather than objects, are used for these quantities for the sake
of performance. Using objects for these values would add an unacceptable overhead to even the simplest
of calculations. Thus, the primitive types are not part of the object hierarchy, and they do not inherit
Object. Despite the performance benefit offered by the primitive types, there are times when you will
need an object representation. For example, you can’t pass a primitive type by reference to a method.
Also, many of the standard data structures implemented by Java operate on an object, which means that
you can’t use these data structures to store primitive types. To handle these (and other) situations, Java
provides type wrappers, which are classes that encapsulate a primitive type within an object.
The type wrappers are Double, Float, Long, Integer, Short, Byte, Character, and Boolean. These
classes offer a wide array of methods that allow you to fully integrate the primitive types into Java’s object
hierarchy.
Primitive Wrapper
boolean java.lang.Boolean
byte java.lang.Byte
char java.lang.Character
double java.lang.Double
float java.lang.Float
int java.lang.Integer
long java.lang.Long
short java.lang.Short
void java.lang.Void
• Character Wrappers: Character is a wrapper around a char. The constructor for Character is
Character(char ch)
Here, ch specifies the character that will be wrapped by the Character object being created. To obtain the
char value contained in a Character object, call charValue(), shown here:
char charValue( )
It returns the encapsulated character.
• Boolean Wrappers: Boolean is a wrapper around boolean values. It defines these constructors:
Boolean(boolean boolValue)
Boolean(String boolString)
In the first version, boolValue must be either true or false. In the second version, if boolString contains
the string “true” (in uppercase or lowercase), then the new Boolean object will be true. Otherwise, it will
be false. To obtain a boolean value from a Boolean object, use
boolean booleanValue( )
It return the boolean equivalent of the invoking object.
• The Numeric Type Wrappers: The most commonly used type wrappers are those that represent
numeric values. All of the numeric type wrappers inherit the abstract class Number. Number
declares methods that return the value of an object in each of the different number formats. These
methods are shown here:
• byte byteValue( )
• double doubleValue( )
• float floatValue( )
• int intValue( )
• long longValue( )
• short shortValue( )
For example, doubleValue( ) returns the value of an object as a double, floatValue( ) returns the value as a
float, and so on. These methods are implemented by each of the numeric type wrappers.
All of the numeric type wrappers define constructors that allow an object to be constructed from a given
value, or a string representation of that value. For example, here are the constructors defined for Integer:
If str does not contain a valid numeric value, then a NumberFormatException is thrown. All of the type
wrappers override toString(). It returns the human-readable form of the value contained within the wrapper.
This allows you to output the value by passing a type wrapper object to println(), for example, without
having to convert it into its primitive type.
class TypeWrap
{
public static void main(String args[])
{
Character ch=new Character('#');
System.out.println("Character is " + ch.charValue());
Boolean b=new Boolean(true);
System.out.println("Boolean is " + b.booleanValue());
Boolean b1=new Boolean("false");
System.out.println("Boolean is " + b1.booleanValue());
Character is #
Boolean is true
Boolean is false
12 is same as 12
x is 21
s is 25
Prof K RADHIKA, Dept of CSE SSCE, Anekal
REGULATION 2022 SCHEME. OOP WITH JAVA - BCS306A
Autoboxing
Autoboxing refers to the conversion of a primitive value into an object of the corresponding wrapper class.
For example, converting int to Integer class. The Java compiler applies autoboxing when a primitive value
is:
• Passed as a parameter to a method that expects an object of the corresponding wrapper class.
• Assigned to a variable of the corresponding wrapper class.
Unboxing on the other hand refers to converting an object of a wrapper type to its corresponding primitive
value. For example conversion of Integer to int. The Java compiler applies to unbox when an object of a
wrapper class is:
• Passed as a parameter to a method that expects a value of the corresponding primitive type.
• Assigned to a variable of the corresponding primitive type.
Example:
class AutoBox {
Output:
100 100
In addition to the simple case of assignments, autoboxing automatically occurs whenever a primitive type
must be converted into an object; auto-unboxing takes place whenever an object must be converted into a
primitive type. Thus, autoboxing/unboxing might occur when an argument is passed to a method, or when a
value is returned by a method. For example:
Output:
100
In general, autoboxing and unboxing take place whenever a conversion into an object or from an object is
required. This applies to expressions. Within an expression, a numeric object is automatically unboxed. The
outcome of the expression is reboxed, if necessary. For example, consider the following program:
class AutoBox3 {
public static void main(String args[]) {
Integer iOb, iOb2;
int i;
iOb = 100;
System.out.println("Original value of iOb: " + iOb);
// The following automatically unboxes iOb,
// performs the increment, and then reboxes
// the result back into iOb.
++iOb;
System.out.println("After ++iOb: " + iOb);
// Here, iOb is unboxed, the expression is
// evaluated, and the result is reboxed and
// assigned to iOb2.
iOb2 = iOb + (iOb / 3);
System.out.println("iOb2 after expression: " + iOb2);
Prof K RADHIKA, Dept of CSE SSCE, Anekal
REGULATION 2022 SCHEME. OOP WITH JAVA - BCS306A
}}
Auto-unboxing also allows you to mix different types of numeric objects in an expression. Once the values
are unboxed, the standard type promotions and conversions are applied. For example, the following program
is perfectly valid:
class AutoBox4 {
Output:
Java also supplies wrappers for boolean and char. These are Boolean and Character. Autoboxing/unboxing
applies to these wrappers, too. For example, consider the following program:
class AutoBox5 {
// Autobox/unbox a boolean.
Boolean b = true;
// Autobox/unbox a char.
Output:
b is true
ch2 is x