KEMBAR78
UNIT-4 OOP Lecture Notes | PDF | Thread (Computing) | Process (Computing)
0% found this document useful (0 votes)
16 views105 pages

UNIT-4 OOP Lecture Notes

Unit 4 discusses multithreading in Java, explaining the concepts of single and multitasking, and the advantages of multithreading such as efficiency and independence of threads. It covers the creation of threads through extending the Thread class and implementing the Runnable interface, along with examples of thread life cycles and daemon threads. Additionally, it introduces the concept of thread pools for better performance in managing multiple threads.

Uploaded by

bhargavialluri30
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views105 pages

UNIT-4 OOP Lecture Notes

Unit 4 discusses multithreading in Java, explaining the concepts of single and multitasking, and the advantages of multithreading such as efficiency and independence of threads. It covers the creation of threads through extending the Thread class and implementing the Runnable interface, along with examples of thread life cycles and daemon threads. Additionally, it introduces the concept of thread pools for better performance in managing multiple threads.

Uploaded by

bhargavialluri30
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 105

Unit- 4 – Multithreading

Multi Threading in Java Types of tasking Two types of tasking 1.Single Tasking 2.Multi
Thread Tasking
➢Thread is a lightweight process. Single Tasking
➢A thread is a single flow of statements which are Performing single task at a time.
under execution. Multi Tasking
➢A thread is part of the It is the concurrent execution of multiple tasks over a
certain period of time.
program which can
perform a specific task. Multi Threading in Java
Multithreading in Java is a
process of executing multiple threads
simultaneously.
Java Multithreading is mostly used
in games,
animation, etc.
Advantages of Java Multithreading
1)It doesn't block the user because threads are independent,
and we can perform multiple operations at the same time.
2)We can perform many operations together, so it
saves time.
Program A well defined set of instructions 3)Threads are independent, so it doesn't affect other threads if
an exception occurs in a single thread.
Process Program under execution
Difference between Multi Threading and Multi Tasking

Multi-Threading Multi Tasking

1.It is a programming language concept in which a 1. It is an operating system concept in which


program or process is divided into two or more multiple tasks are performed simultaneously.
subprograms that are executed at the same time in
parallel. 2. It is less efficient than Multi-threading.
2.It is highly efficient. 3. It supports execution of
3.It supports execution of multiple parts of a multiple programs
Dsingle program simultaneously. simultaneously.
4.The processor must switch between 4. The processor must switch between different
different parts or threads of a program. programs or processes.
5.A thread is the smallest unit in multi- 5. A program or process is the smallest unit in
threading. multitasking.
6.It is cost effective in case 6. It is expensive in case of context switching.
of context
switching. 7. It helps in developing efficient
7.It helps in developing efficient programs. operating
systems.
2.Inside the class it have one method name as public void run()

Syntax
Creation of Thread class A extends Thread
Threads can be created by using two {
public void run()
mechanisms :
{
1. Extending the Thread class …
2. Implementing the Runnable Interface ..
}
1.Thread creation by extends Thread class }
Steps
3.Write main class with main()
1.Write one class that extends Thread class
4.Create object to the class in step 1
Syntax Syntax
class keyword classname extends keyword Classname object=new operator Classname()
thread class
Ex: class A extends Thread 5.Using the created object in step 4 call the start method
Syntax
classobject.start()
Example for Creation of the Thread using extends Thread class
import java.io.*;
//Creation of Thread1
class A extends Thread
{
public void run()
{
for(int i=0;i<10;i++) Output
{
System.out.println("A Thread="+i); A Thread=0 A Thread=1 A Thread=2 A Thread=3 A Thread=4
} A Thread=5 A Thread=6 A Thread=7 A Thread=8 A Thread=9
}
}
//main class
class crthr
{
public static void main(String args[])
{
//create object to the class
A a1=new A();
//call the start method using created object a1.start();

}
}
Example for Creation of Multiple Threads using extends Thread class
import java.io.*; //main class
//Creation of Thread1
class A extends Thread class multhr
{ {
public void run() public static void main(String args[])
{
{
//create object to the classes
for(int i=0;i<10;i++)
A a1=new A(); B b1=new B();
{ //call the start method using created object
System.out.println("A Thread="+i); a1.start();
} b1.start();
} }
} }
//Creation of Thread2
class B extends Thread
{
public void run()
{
for(int j=0;j<10;j++)
{
System.out.println("B Thread="+j);
}
}
}
Output
B Thread=0 A Thread=0 B Thread=1 A Thread=1 B
Thread=2 A Thread=2 B Thread=3 A Thread=3 B
Thread=4 A Thread=4 B Thread=5 A Thread=5 B
Thread=6 A Thread=6 B Thread=7 A Thread=7 B
Thread=8 A Thread=8 B Thread=9 A Thread=9
2.Thread creation by using implements
Runnable interface
Steps 3.Write main class with main()

1.Write one class that implements Runnable interface 4.Create object to the class in step 1
Syntax
Syntax Classname object=new operator Classname()
Class keyword classname implements Runnable Ex: Class A
implements Runnable 5.Create object to the Thread class and attach class object in
step4
2.Inside the class it have one method name as public void Thread class object=new operator Thread class(class
run() object);
Syntax
Class A implements Runnable
{ 6.Using the created object in step 5 call the start
public void run() method
{
… Syntax
.. threadobject.start()

}
}
Example for Creation of the Thread using implements Runnable interface

import java.io.*;
class A implements Runnable
{
public void run()
{
for(int i=0;i<10;i++)
{ Output
System.out.println("A Thread="+i);
} A Thread=0 A Thread=1 A Thread=2 A Thread=3 A Thread=4
} A Thread=5 A Thread=6 A Thread=7 A Thread=8 A Thread=9
}
class crthr1
{
public static void main(String args[])
{

//create object to the class A a1=new A();


//create object to Thread and attach class object
Thread t1=new Thread(a1);
//call the start method using created object
t1.start();

}
}
Example for Creation of Multiple Threads using implements Runnable interface
import java.io.*;
//Creation of Thread1 //main class
class A extends Thread
{ class multhr1
public void run() {
{ public static void main(String args[])
for(int i=0;i<10;i++) {
{ //create object to the classes
System.out.println("A Thread="+i); A a1=new A();
} B b1=new B();
} //create objects to Thread class Thread t1=new Thread(a1);
} Thread t2=new Thread(b1);
//Creation of Thread2 //call the start method using created thread objects
t1.start();
class B extends Thread
t2.start();
{
}
public void run()
}
{
for(int j=0;j<10;j++)
{
System.out.println("B Thread="+j);
}
}
}
Output
B Thread=0 A Thread=0 B Thread=1 A Thread=1 B
Thread=2 A Thread=2 B Thread=3 A Thread=3 B
Thread=4 A Thread=4 B Thread=5 A Thread=5 B
Thread=6 A Thread=6 B Thread=7 A Thread=7 B
Thread=8 A Thread=8 B Thread=9 A Thread=9
Thread Life Cycle

After creation of any thread each


thread have the following states.
1.New/Born State
2.Runnable State
a)Running State
b)Queued/Waiting State 3.Blocked State
4.Dead/Terminated State

The life cycle of the thread in java


is controlled by JVM.
1) New state/born state
The thread is in new state if you create an instance of
Thread class but before the invocation of start() a.Running state
Wh en th read is execu ting , it’s state is changed to
method.
Running. When the thread is in running state then it
A newly created thread that has not yet started the is u nder execu tion . H ere th read can perform s an
execution. action .
It remains in this state until the program starts the Then C P U starts executing this thread. A thread can
thread. It is also referred to as a born thread. change state to Runnable, Dead or B locked from
ru nning state depends on time slicing, th read
com pletion of ru n() m eth od or waiting for some
2) Runnable state resources.
b. Blocked/Waiting state:
The thread is in runnable state after invocation of
A thread is in the Blocked state when it's currently not
start() method, but the thread scheduler has not eligible to run.
selected it to be the running thread. When a thread is temporarily inactive, then it’s in one of the
After a newly born thread is started, the following states:
thread becomes runnable. a)Blocked
This state defines either running or ready for b)Waiting
execution but it's waiting for resource A thread is in the blocked state when it tries to access a
allocation protected section of code that is currently locked by some
other thread.
Dead lock of threads in java
3.Waiting State
A thread is in Waiting state when it's waiting for t1 t2
some other thread to perform a particular action.

when a thread is waiting for I/O to complete, it


lies in the blocked state.
A thread in this state cannot continue its execution r1 r2
any further until it is moved to runnable state. Any
thread in these states does not consume any CPU resource resource
cycle.
A thread t1 is pointed/hold by its own
4.Dead State/Terminated State resource r1 and at the same time waiting for
another resource r2 at the same time thread
t2 is already pointed/hold by its own
Once the thread finished executing, it’s state is
resource r2 and waiting for another resource
changed to Dead and it’s considered to be not alive. r1 which is already attached to t1.Here
A runnable thread enters the terminated state when it deadlock occurs.
completes its task or otherwise terminates. Inside the deadlock of threads the threads are
in safe mode.
J a v a Thread Method
J a v a Thread Method
J a v a Thread Method
J a v a Thread Method
J a v a Thread Method
J a v a Thread Method – joining of threads – join()
J a v a Thread Method – Priorities of thread

.getName());
J a v a Thread Method

.getPriority());
J a v a Thread Method – Naming a thread
J a v a Thread Method
J a v a Thread Method
J a v a Thread Method
11. public final boolean isAlive()
public class JavaIsAliveExp extends Thread
{
public void run()
{
try
{
Thread.sleep(300);
System.out.println("is run() method isAlive "+Thread.currentThread().isAlive());
}
catch (InterruptedException ie) {
}
}
public static void main(String[] args)
{
JavaIsAliveExp thread1 = new JavaIsAliveExp(); System.out.println("before starting
thread isAlive: "+thread1.isAlive()); thread1.start();
System.out.println("after starting thread isAlive: "+thread1.isAlive());
}
}
J a v a Thread Method
E x amples

1.Creates three threads in which First thread displays “Good Morning” every one second,
the Second thread displays “Hello” every two seconds and the third thread displays
“Welcome” every three seconds.

2.Develop a java program that implements a multi-threaded program, which has three
threads. First thread generates a random integer for every 1 second, if the generated
integer is even the second thread computes the square of the number and print it. If the
generated integer is odd the third thread will print the value of cube of the number.
Daemon Thread
➢ Daemon thread in J av a is also a service provider thread that provides services to the user thread.

when all the user threads die, J V M terminates this thread automatically.

➢ Daemon thread in J av a is a low-priority thread that runs in the background to perform tasks

such as garbage collection.

❖ Properties of J ava Daemon Thread :

➢ It is an utmost low priority thread.

➢ If J V M finds a running daemon thread, it terminates the thread an d, after that, shutdown it.

➢ J V M does not care whether the Daemon thread is running or not.

➢ They can not prevent the J V M from exiting when all the user threads finish their execution.

Note: Whenever the last non-daemon thread terminates, all the daemon threads will be terminated
automatically.
Methods of Daemon Thread
1. void setDaemon(boolean status):
This method marks the current thread as a daemon thread or user thread.
For example, if I have a user thread tU then tU.setDaemon(true) would make it a Daemon thread.
O n the other hand, if I have a Daemon thread tD then calling tD.setDaemon(false) would make it
a user thread.

Syntax: public final void setDaemon(boolean on)


Parameters: on: If true, marks this thread as a daemon thread.

2. boolean isDaemon():
This method is used to check that the current thread is a daemon. It returns true if the thread is Daemon. Else, it
returns false.

Syntax: public final boolean isDaemon()


Ret urns: This method returns true if this thread is a daemon thread; false otherwise
Example-1 of Daemon Thread

public class DaemonThread extends Thread


public static void main(String[] args)
{
{
public DaemonThread(String name)
{
super(name); DaemonThread t1 = new DaemonThread("t1");
} DaemonThread t2 = new DaemonThread("t2");
DaemonThread t3 = new DaemonThread("t3");
public void run()
{ // Setting user thread t1 to Daemon t1.setDaemon(true);
if(Thread.currentThread().isDaemon())
{ // starting first 2 threads
System.out.println(getName() + " is t1.start();
Daemon thread"); t2.start();
}
else // Setting user thread t3 to Daemon t3.setDaemon(true);
{ t3.start();
System.out.println(getName() + " is User thread"); }
} }
}
Example-2 of Daemon Thread

public class DaemonThread extends Thread public static void main(String[] args)
{ {

public void run() DaemonThread t1 = new DaemonThread();


{ DaemonThread t2 = new DaemonThread();

System.out.println("Thread name: " + t1.start();


Thread.currentThread().getName());
/ / Exception as the thread is already started
System.out.println("Check if its DaemonThread: “ + t1.setDaemon(true);
Thread.currentThread().isDaemon());
t2.start();
} }
}
Example of Daemon Thread
Thread Pool
➢ In thread pool, a group of fixed-size threads is
Since the thread is already existing when the request
created.
arrives, the delay introduced by thread creation is
➢ A thread from the thread pool is pulled out and
eliminated, making the application more responsive.
assigned a job by the service provider.
➢ After completion of the job, the thread is contained in
the thread pool again.
➢ So, Java Thread pool represents a group of worker
threads that are waiting for the job and reused many
times.

Advantage of Java Thread Pool :

Better performance It saves time.

Real time usage :

It is used in Servlet and JSP where the container


creates a thread pool to process the request.
Thread Pool
Steps to be followed :

1. Create a task (Runnable Object) to execute.


➢ Create a class which only implements Runnable interface and includes run() which represents the task
need to be performed (place that in a queue, automatically performed by ThreadPoolExecutor class)

2. Create Executor Pool using Executors and ExecutorService.

➢ Create a thread of pools with MAX_T no. of threads as of pool size.

➢ Create an object under ExecutorService and pass the parameter as the number of threads created in a pool

using Executors method.

3. Pass tasks to Executor Pool

➢ Pass the Task objects to the pool to execute. ( use execute() method)

4. Shutdown the Executor Pool.


use the shutdown() method.
Executors Thread Pool Methods

1. newFixedThreadPool(int s): Creates a thread pool of the fixed size s.

2. newCachedThreadPool(): Creates a thread pool that creates new threads as needed but will

reuse previously constructed threads when they are available.

3. newSingleThreadExecutor(): The method creates a new thread.

Note: In case of a fixed thread pool, if all threads are being currently run by the executor, then the

pending tasks are placed in a queue and are executed when a thread becomes idle.
Example - Thread Pool
Date d = new Date();
SimpleDateFormat ft = new SimpleDateFormat("hh:mm:ss");
import java.text.SimpleDateFormat; import
java.util.Date; System.out.println("Initialization Time for - " + name + " = "
import java.util.concurrent.ExecutorService; +ft.format(d));
import java.util.concurrent.Executors; //prints the initialization time for every task
}
class Task implements Runnable else
/ / Task class to be executed (Step 1) {
{ Date d = new Date();
String name; SimpleDateFormat ft = new SimpleDateFormat("hh:mm:ss");
Task(String s)
{ S ystem .out . println("Executing Time for - "+ name +" = "
name = s; +ft.format(d));
} / / prints the execution time for every task
public void run() }
{ Thread.sleep(1000);
try }
{ System.out.println(name+" complete");
for (int i = 0; i<=3; i++) }
{ catch(InterruptedException e)
if (i==0) {
{ e.printStackTrace();
}
} }
Example - Thread Pool
public class Test_pool
{
static final int MAX_T = 3; / / Maximum number of threads in thread pool

public static void main(String[] args)


{
Task r1 = new Task("task 1"); / / creates five tasks
Runnable r2 = new Task("task 2");
Runnable r3 = new Task("task 3");
Runnable r4 = new Task("task 4");
Runnable r5 = new Task("task 5");

/ / creates a thread pool with MAX_T no. of threads as the fixed pool size (Step 2)

ExecutorService ExeSerObj = Executors.newFixedThreadPool(MAX_T);

ExeSerObj.execute(r1); / / passes the Task objects to the pool to execute (Step 3)


ExeSerObj.execute(r2);
ExeSerObj.execute(r3);
ExeSerObj.execute(r4);
ExeSerObj.execute(r5);

ExeSerObj.shutdown(); / / pool shutdown (Step 4)


}
}
Example - Thread Pool
newCachedThreadPool()
newSingleThreadExecutor()
Thread Synchronization
➢ Synchronization in java is the capability to control
the access of multiple threads to any shared Why use Synchronization?
resource. The synchronization is mainly used to :
➢ Thread Synchronization is a process of allowing only 1. If you start with at least two threads inside a program,
one thread to use the object when multiple threads there might be a chance when multiple threads attempt

are trying to use the object at the same time. to get to the same resource.

➢ To achieve this Thread Synchronization, we must use 2. It can even create an unexpected outcome because of

a keyword called “synchronized”. concurrency issues.

General Syntax: Thread Synchronization:


synchronized (objectidentifier) 1. Mutual Exclusive
{ 2. Cooperation (Inter-thread communication)
// Access shared variables and other shared resources;
}
Thread Synchronization

Mutual Exclusive :

Mutual Exclusive helps keep threads from interfering


with one another while sharing data.

Mutual Exclusion can be achieved by three ways in java:

1. Synchronized Method
2. Synchronized Block
3. Static Synchronization
Understanding the problem without synchronization
public class Sync_exam implements Runnable
public void run ()
{
{
int tickets = 3;
String name= Thread.currentThread().getName ();
public void bookticket (String name, int
if (name.equals ("t1"))
wantedtickets)
{
{
bookticket (name, 1);
if (wantedtickets <= tickets)
}
{
System.out.println (wantedtickets + "
booked to " + name); else if (name.equals ("t2"))
tickets = tickets - wantedtickets; {
} bookticket (name, 2);
}
else
{ else
System.out.println ("No tickets to book {
for" + name); bookticket (name, 3);
} }
} }
Understanding the problem without synchronization

public static void main (String[]args)


{
Sync_exam s = new Sync_exam ();

Thread t1 = new Thread (s);


Thread t2 = new Thread (s);
Thread t3 = new Thread (s);

t1.setName ("t1");
t2.setName ("t2");
t3.setName ("t3");

t1.start ();
t2.start (); In above, objects of class Sync_exam is shared by all the three running
t3.start ();
threads(t1, t2, and t3) to call the shared method(void bookticket).
}
} Hence the result is non-synchronized and such a situation is called a “Race
condition”.
I . Synchronized Method
II. Synchronized Block

Suppose we have 50 lines of code in our method, but


➢ B lock-level syn ch ronization is used for
making some amount of method code is thread-safe. we want to synchronize only 5 lines, in such cases, we
can use synchronized block.
➢ If we want to synchronize access to an object of a
class or only a part of a method to be synchronized,
If we put all the codes of the method in the
then we can use the synchronized block for it.
synchronized block, it will work same as the
➢ It is capable to make any part of the object
synchronized method.
and method synchronized.

Scope of synchronized block is smaller than the


Syntax:
method.
synchronized (object reference expression)
{
//code block Synchronized block is more efficient than synchronized
} method.
Example without Synchronization
class AB extends Thread
{
class SyncBlock1
int token = 1, a=4, b=5, sum;
{
public void run ()
public static void main (String[]args)
{
{
String name = Thread.currentThread().getName ();
AB ab1 = new AB ();
AB ab2 = new AB ();
System.out.println (token + " tokens allotted to..... " +
AB ab3 = new AB ();
name);
token++;
ab1.setName("thread1");
ab2.setName("thread2");
sum=a+b;
ab3.setName("thread3");
System.out.println("Sum of " +a + " and " +b +" is "
+sum);
ab1.start ();
a++;
ab2.start ();
b++;
ab3.start ();
}
System.out.println("a is "+a + " b is " +b);
System.out.println(" "); }
}
}
Example without Synchronization - Output
Example with Block Synchronization
class AB implements Runnable
{
int token = 1, int a=4, b=5, sum;
public void run () class SyncBlock2
{ {
synchronized(this) public static void main (String[] args)
{ {
String name = Thread.currentThread().getName (); AB ab1 = new AB ();
System.out.println (token + " tokens alloted to..... " + Thread t1 = new Thread (ab1);
name); Thread t2 = new Thread (ab1);
token++; Thread t3 = new Thread (ab1);
}
sum=a+b; t1.setName("thread1");
System.out.println("Sum of " +a + " and " +b +" is " t2.setName("thread2");
+sum); t3.setName("thread3");
a++; b++;
System.out.println("a is "+a + " b is " +b); t1.start ();
System.out.println(" "); t2.start ();
} t3.start ();
} }
}
Output
Static Synchronization

➢ In simple words, a static synchronized method will lock the class instead of the
object, and it will lock the class because the keyword static means: “class instead
of instance”.

➢ The keyword synchronized means that only one thread can access the method
at a time.

➢ And static synchronized mean: Only one thread can access the class at one
time.
Example with Static Synchronization

class Table class MyThread21 extends Thread


{ {
synchronized static void printTable (int n) public void run ()
{ {
for (int i = 1; i <= 10; i++) Table.printTable (10);
{ }
System.out.println (n * i); }
try { Thread.sleep (400); }
catch (InterruptedException e){ } public class StaticSynchronization
} {
System.out.println(" "); public static void main (String t[])
} {
} MyThread10 t1 = new MyThread10 ();
MyThread21 t2 = new MyThread21 ();
class MyThread10 extends Thread
{ t1.start ();
public void run () { t2.start ();
Table.printTable (1);
} }
} }
Example with Static Synchronization
Example without Static Synchronization
Inter Thread Communication

➢ It is a mechanism of communication between two threads or multiple threads that acts on the

common object or shared resources.

➢ To perform the multiple actions at a time we need Inter-thread communication.

➢ For example, online video player, audio player, etc. In both types of players generally, there are two

types of threads: Buffer Thread and Playing Thread.

➢ Buffer Thread is responsible to download content from the server into a buffer memory and

whereas playing thread is responsible to play content and these actions will be done based on

thread communication only.


Methods to Perform Inter Thread Communication

1. wait(): This method is used to make the Thread wait until it gets a notification. This method pauses the current thread to the
waiting room dynamically.

2. notify(): This method is used to send the notification to one of the waiting thread so that thread enters running state and
execute the remaining task.

This method wakeup a single thread into the active state (that acts on the common object).

3. notifyAll(): This method is used to send the notification to all the waiting threads so that all thread enters running state and
execute simultaneously.

This method wakes up all the waiting threads that act on the common objects.
Note:
➢ We must call wait(), notify() and notifyAll() methods inside the synchronized blocks or synchronized methods, otherwise it
will throw a Runtime Exception called IllegalMonitorStateException.
➢ By using these methods, we can resolve problems like Producer-Consumer Problem.
Process of Inter Thread Communication

1. Threads enter to acquire lock.

2. Lock is acquired by one thread.


3. Now thread goes to waiting state if you call
wait() method on the object. Otherwise, it
releases the lock and exits.
4. If you call notify() or notifyAll() method, thread
moves to the notified state (runnable state).

5. Now thread is available to acquire lock.

6. After completion of the task, thread releases


the lock and exits the monitor state of the object.
Process of Inter Thread Communication
Inter Thread Communication - Example
class Customer{ class Test_inter
int amount=10000; {
public static void main(String args[]) { Customer
synchronized void withdraw(int amount) c=new Customer();
{
System.out.println("going to withdraw..."); Thread T1 = new Thread()
if(this.amount<amount) {
{ public void run()
System.out.println("Less balance; waiting for {
deposit..."); c.withdraw(15000);
try{ wait(); }catch(InterruptedException e){ } }
} };
this.amount-=amount;
System.out.println("withdraw completed..."); Thread T2 = new Thread()
} {
public void run()
synchronized void deposit(int amount) {
{ c.deposit(10000);
System.out.println("going to deposit..."); }
this.amount+=amount; System.out.println("deposit };
completed... "); notify();
} T1.start();
} T2.start(); }
}
Producer-Consumer solution using threads
Problem:
➢ The producer-consumer problem (also known as the
To make sure that the producer won’t try to add data
bounded-buffer problem) is an example of a multi-
into the buffer if it’s full and that the consumer won’t try
process synchronization problem.
to remove data from an
empty buffer.
➢ The problem describes two processes or
Solution:
threads, the producer and the
The producer is to either go to sleep or discard data if
consumer,
which share a common, fixed-size buffer used
the buffer is full. The next time when the consumer
as a queue.
removes an item from the buffer, it notifies the producer,
➢The producer’s job is to generate data, put it into
who starts to fill the buffer again.
the buffer, and start again.
In the same way, the consumer can go to sleep if it finds
➢At the same time, the consumer is consuming the
the buffer to be empty. The next time the producer puts
data (i.e., removing data from the buffer), one piece
data into the buffer, it wakes up the sleeping consumer.
at a time.
Producer-Consumer solution using threads
class Buffer{
public synchronized void consume(){
int a;
if(!produced)
boolean produced = false;
{
public synchronized void produce(int x){
System.out.println("Consumer is waiting...");
if(produced){
try{ wait(); } catch(InterruptedException e){ }
System.out.println("Producer is waiting...");
try{ wait(); }catch(InterruptedException e){ }
}
}
System.out.println("Product" + a + " is
a=x;
consumed.");
System.out.println("Product“ + a + " is
produced = false;
produced.");
produced = true; notify();

notify(); }

} }
Producer-Consumer solution using threads
class Producer extends Thread{ class Consumer extends Thread{
Buffer b; Buffer b;
public Producer(Buffer b){ public Consumer(Buffer b){
this.b = b; this.b = b;
} }

public void run(){ public void run(){


System.out.println("Producer start System.out.println("Consumer start
producing..."); consuming...");
for(int i = 1; i <= 10; i++){ for(int i = 1; i <= 10; i++){
b.produce(i); b.consume();
} }
} }
} }
Producer-Consumer solution using threads
public class ProducerConsumerExample {
public static void main(String args[]){
//Create Buffer object.
Buffer b = new Buffer();

//creating producer thread.


Producer p = new Producer(b);

//creating consumer thread.


Consumer c = new Consumer(b);

//starting threads.
p.start();
c.start();
}
}
Unit- 4 – Collection Framework
Java Collection :
➢ Java collections refer to a collection of
▪ Interfaces: Interfaces are the reference
individual objects that are represented as a
types which are like classes but contains
single unit.
only abstract methods.
➢ Can perform all operations such as searching,
▪ They allow Java collections to be manipulated
sorting, insertion, manipulation, deletion, etc.,
independently from the details of their
on Java collections just like doing it on data.
representation. Also, they form a hierarchy in
What is a Java Collection Framework?
OOPs languages.
➢ A Java collection framework provides an
architecture to store and manipulate a group
▪ Classes: Classes in Java are the
of objects.
implementation of the collection interface.
➢ A Java collection framework includes the
▪ It basically refers to the data structures
following:
that are used again and again.
▪ Interfaces
▪ Classes
▪ Algorithm 1
Why use Java collection?
There are several benefits of using Java
collections such as:
▪ Algorithm: Algorithm refers to the methods
▪ Reducing the effort required to write the code
which are used to perform operations such as
by providing useful data structures and
searching and sorting, on objects that
algorithms.
implement collection interfaces.
▪ Java collections provide high-performance and
high-quality data structures and algorithms
▪ Algorithms are polymorphic in nature as the
thereby increasing the speed and quality.
same method can be used to take many
▪ Unrelated APIs can pass collection interfaces
forms or you can say perform different
back and forth.
implementations of the Java collection
▪ Decreases extra effort required to learn, use,
interface.
and design new API’s.
▪ Supports reusability of standard data
structures and algorithms.
2
Collection Framework Hierarchy
Java collection framework includes interfaces and classes.

3
Java Collection : Interface

4
Java Collection : Interface

Iterator interface :
▪ Iterator is an interface that iterates the elements.
▪ It is used to traverse the list and modify the elements.
▪ Iterator interface has three methods which are mentioned below:
1. public boolean hasNext() – This method returns true if the iterator has
more elements.
2. public object next() – It returns the element and moves the cursor
pointer to the next element.
3. public void remove() – This method removes the last elements returned
by the iterator.
5
Java Collection : List
There are three components that extend the Collection interface i.e List, Queue and
Sets.

6
ArrayList
➢ ArrayList is the implementation of List Interface where the elements can be dynamically added or
removed from the list.
➢ Also, the size of the list is increased dynamically if the elements are added more than the initial
size.
➢ Syntax: ArrayList object = new ArrayList ();
ArrayList Vs Array
➢ In Java, we need to declare the size of an array before we can use it. Once the size of an array is
declared, it's hard to change it.
➢ To handle this issue, we can use the ArrayList class.
➢ It allows us to create resizable arrays.
➢ Unlike arrays, ArrayList can automatically adjust
its capacity when we add or remove elements from it.

Hence, ArrayList are also known as dynamic arrays.

7
ArrayList

Some of the methods in array list are listed below:


Method Description
boolean add(Collection c) Appends the specified element to the end of a list.
void add(int index, Object
Inserts the specified element at the specified position.
element)
void clear() Removes all the elements from this list.
Return the index in this list of the last occurrence of the specified
int lastIndexOf(Object o)
element, or -1 if the list does not contain this element.
Object clone() Return a shallow copy of an ArrayList.
Object[] toArray() Returns an array containing all the elements in the list.
Trims the capacity of this ArrayList instance to be the list’s current
void trimToSize()
size.

8
ArrayList
Create ArrayList in Java:
➢ ArrayList<Type> arrayList= new ArrayList<>();

Here, Type indicates the type of an arraylist. For Basic Operations on ArrayList
example, The ArrayList class provides various methods to
// create Integer type arraylist perform different operations on ArrayList.
ArrayList<Integer> arrayList = new ArrayList<>();

Some commonly used ArrayList operations are:


// create String type arraylist
ArrayList<String> arrayList = new ArrayList<>(); ▪ Add elements
▪ Access elements
In the above program, we have used Integer not int. It ▪ Change elements
is because we cannot use primitive types while creating ▪ Remove elements
an arraylist. Instead, we must use the corresponding
wrapper classes.
Here, Integer is the corresponding wrapper class of int.
9
Example of ArrayList (Prog. 9a.)
import java.util.ArrayList; list2.add("LBRCE");
import java.util.*; list2.add(10);
public class ListDemo { list2.add("2.2");
public static void main(String args[]) { Student s1 = new Student();
// list1 can only store String Objects (Type Specific) s1.roll = 101;
ArrayList<String> list1 = new s1.name = "Ramesh";
ArrayList<String>(); list2.add(s1); //refer to hash code
// list2 can store any type of objects (Any type of // Print reference to list ---> shall print elements
data) from the list the way we added in a sequence
ArrayList list2 = new ArrayList(); System.out.println("List 1 is :"+list1);
// 1. Add Data in List System.out.println("List 2 is :"+list2);
list1.add("Suresh"); //0 // 2. Get the elements from List
list1.add("Mahesh"); //1 String name = list1.get(2);
list1.add("Ganesh"); //2 System.out.println("name is: "+name);
list1.add("Rama"); //3 Object o = list2.get(2);
//list1.add(10); // error // as we doesn't know the type of list2
//list1.add(2.2); // error System.out.println("o is: "+o); 10
Example of ArrayList (Prog. 9a.) (Cont..)
//3. Update Elements in List
System.out.println("==== Iterating with Iterator====");
list1.set(2, "PVPSIT");
Iterator<String> itr = list1.iterator();
System.out.println("list1 now is: "+list1);
//4. Remove Element from List /*System.out.println(itr.next());
System.out.println(itr.next());
list1.remove(2);
System.out.println(itr.next()); */
System.out.println("list1 after remove is: "+list1);
while(itr.hasNext())
//list1.clear(); ---> Remove all
{
if(list1.contains("Mahesh")) { String str = itr.next();
System.out.println(str);
System.out.println("Mahesh is in the List "); }
if(str.equals("Suresh")){
// 5. Iterate in ArrayList - many ways itr.remove();
System.out.println("==== Iterating with For }
loop===="); }
for(int i=0;i<list1.size();i++) { System.out.println("========");
System.out.println(list1.get(i)); } System.out.println("list1 after iteration is: "+list1);
System.out.println("========"); }
}
System.out.println("==== Iterating with Enhanced For- class Student{
each loop===="); int roll;
for(String str : list1) { String name;
System.out.println(str); } }
System.out.println("========"); 11
Example of ArrayList (Prog. 9a.) (Cont..)

12
LinkedList
➢ Linked List is a sequence of links which contains items. Each link contains a connection to
another link. Java Linked List class uses two types of Linked list to store the elements:
Syntax: Linkedlist object = new Linkedlist();

Singly Linked List: In a singly Linked list each Doubly Linked List: In a doubly Linked list, it
node in this list stores the data of the node and has two references, one to the next node and
a pointer or reference to the next node in the another to previous node.
list.

13
LinkedList

Some of the methods in linked list are listed below:


Method Description
boolean add( Object o) It is used to append the specified element to the end of the vector.

boolean contains(Object o) Returns true if this list contains the specified element.

void add (int index, Object


Inserts the element at the specified element in the list.
element)

void addFirst(Object o) It is used to insert the given element at the beginning.

void addLast(Object o) It is used to append the given element to the end.


int size() It is used to return the number of elements in a list

boolean remove(Object o) Removes the first occurrence of the specified element from this list.

Returns the index of the first occurrence of the specified element in


int indexOf(Object element)
this list, or -1.
int lastIndexOf(Object Returns the index of the last occurrence of the specified element in
element) this list, or -1.
14
LinkedList Example -1
import java.util.*; import java.util.*;
public class LinkedListDemo1{ public class LinkedListDemo2 {
public static void main(String args[]) public static void main(String args[]) {
{ LinkedList<String> ll= new LinkedList<>();
LinkedList<String> ll = new LinkedList<String>();
ll.add(“LBRCE");
ll.add(“CSE-A");
// Adding elements to the linked list ll.add(1, “IT");
ll.add("A");
ll.add("B"); // Using the Get method and the for loop
ll.addLast("C"); for (int i = 0; i < ll.size(); i++) {
ll.addFirst("D"); System.out.print(ll.get(i) + " ");
ll.add(2, "E"); }
System.out.println(ll); System.out.println();
ll.remove("B");
// Using the for each loop
ll.remove(3);
for (String str : ll)
ll.removeFirst(); System.out.print(str + " ");
ll.removeLast(); } }
System.out.println(ll);
}} Output:
Output: [D, A, E, B, C] LBRCE IT CSE-A
[A] LBRCE IT CSE-A
15
LinkedList Example - 2

import java.util.*;
public class LinkedlistExample{
public static void main(String args[]){
LinkedList<String>al=new
LinkedList<String>();// creating linked list
The output of the above program would be:
al.add("Rachit"); // adding elements
al.add("Rahul");
Rachit
al.add("Rajat");
Rahul
Iterator<String> itr = al.iterator();
Rajat
while(itr.hasNext()){
System.out.println(itr.next());
}
}
}
16
Vector
➢ Vectors are similar to arrays, where the elements of the vector object can be accessed via an index
into the vector.
➢ Vector implements a dynamic array. Also, the vector is not limited to a specific size, it can shrink
or grow automatically whenever required.
➢ It is similar to ArrayList, but with two differences :
▪ Vector is synchronized.
▪ Vector contains many legacy methods that are not part of the collection's framework.
▪ Syntax: Vector object = new Vector(size,increment);

17
Vector

Vector vs. ArrayList


➢ In Java, both ArrayList and Vector implements the List interface and provides the same
functionalities. However, there exist some differences between them.
➢ The Vector class synchronizes each individual operation. This means whenever we want to
perform some operation on vectors, the Vector class automatically applies a lock to that
operation.
➢ It is because when one thread is accessing a vector, and at the same time another thread tries to
access it, an exception called ConcurrentModificationException is generated. Hence, this
continuous use of lock for each operation makes vectors less efficient.
➢ However, in array lists, methods are not synchronized. Instead, it uses the
Collections.synchronizedList() method that synchronizes the list as a whole.

Note: It is recommended to use ArrayList in place of Vector because vectors less efficient.
18
Vector

19
Methods of Vector

Add Elements to Vector


add(element) - adds an element to vectors
add(index, element) - adds an element to the
specified position
addAll(vector) - adds all elements of a vector
to another vector

20
Methods of Vector

Access Vector Elements


get(index) - returns an element specified by
the index
iterator() - returns an iterator object to
sequentially access vector elements

21
Methods of Vector

Remove Vector Elements


remove(index) - removes an element from
specified position
removeAll() - removes all the elements
clear() - removes all elements. It is more
efficient than removeAll()

22
9b. Develop a java program to perform all the operations in Collection interface.
import java.util.*;
public class CollectionOperationsExample { public
// Check if the collection is empty
static void main(String[] args) {
System.out.println("Is Collection empty? " +
// Create a collection (ArrayList in this case)
myCollection.isEmpty());
Collection<String> myCollection = new
// Removing an element
ArrayList<>();
myCollection.remove("C++");
// Adding elements to the collection
System.out.println("Collection after removing
myCollection.add("Java");
'C++': " + myCollection);
myCollection.add("Python");
// Checking if the collection contains an element
myCollection.add("C++");
System.out.println("Does Collection contain
myCollection.add("JavaScript");
'Java'? " + myCollection.contains("Java"));
// Displaying the elements in the collection
// Clearing the collection
System.out.println("Original Collection: " +
myCollection.clear();
myCollection);
System.out.println("Collection after clearing:
// Size of the collection
" + myCollection);
System.out.println("Size of Collection: " +
myCollection.size()); 23
9b. Develop a java program to perform all the operations in Collection interface.
// Add elements to the cleared collection
myCollection.add("HTML");
myCollection.add("CSS");
System.out.println("Collection after adding new elements: " + myCollection);
// Convert the collection to an array
String[] array = myCollection.toArray(new String[0]);
System.out.println("Array from Collection: " + Arrays.toString(array));
}
}

24
Stack Class

➢ Creates an empty Stack.


Stack<E> stack = new Stack<E>();
Method
boolean empty()
Tests if this stack is empty.
E peek()
Looks at the object at the top of this stack without removing it from the stack.
E pop()
Removes the object at the top of this stack and returns that object as the value.
E push(E item)
Pushes an item onto the top of this stack.
int search(Object o)
Returns the 1-based position where an object is on this stack.
25
Stack Class – Example-1

import java.util.Stack;
public class StackEmptyMethodExample
{
//prints elements of the stack
public static void main(String[] args)
System.out.println("Elements in Stack: " + stk);
{
result = stk.empty();
//creating an instance of Stack class
System.out.println("Is the stack empty? " + result);
Stack<Integer> stk= new Stack<>();
}
// checking stack is empty or not
}
boolean result = stk.empty();
Output:
System.out.println("Is the stack empty? " + result);
Is the stack empty? true
// pushing elements into stack
Elements in Stack: [78, 113, 90, 120]
stk.push(78);
Is the stack empty? false
stk.push(113);
stk.push(90);
stk.push(120);
26
Stack Class – Example-2

public class StackPushPopExample //throws exception if the stack is empty


{ try {
public static void main(String args[]) popelmnt(stk); }
{ catch (EmptyStackException e) {
//creating an object of Stack class System.out.println("empty stack"); }
Stack <Integer> stk = new Stack<>(); }
System.out.println("stack: " + stk); //performing push operation
//pushing elements into the stack static void pushelmnt(Stack stk, int x)
pushelmnt(stk, 20); pushelmnt(stk, 13); {
pushelmnt(stk, 89); pushelmnt(stk, 90); //invoking push() method
pushelmnt(stk, 11); pushelmnt(stk, 45); stk.push(new Integer(x));
pushelmnt(stk, 18); System.out.println("push -> " + x);
//popping elements from the stack //prints modified stack
popelmnt(stk); System.out.println("stack: " + stk);
popelmnt(stk); }
27
Stack Class – Example-2

Output:

stack: []
push -> 20
//performing pop operation
stack: [20]
static void popelmnt(Stack stk) push -> 13
stack: [20, 13]
{
push -> 89
System.out.print("pop -> "); stack: [20, 13, 89]
push -> 90
//invoking pop() method
stack: [20, 13, 89, 90]
Integer x = (Integer) stk.pop(); push -> 11
stack: [20, 13, 89, 90, 11]
System.out.println(x);
push -> 45
//prints modified stack stack: [20, 13, 89, 90, 11, 45]
push -> 18
System.out.println("stack: " + stk);
stack: [20, 13, 89, 90, 11, 45, 18]
} pop -> 18
stack: [20, 13, 89, 90, 11, 45]
}
pop -> 45
stack: [20, 13, 89, 90, 11]
pop -> 11
stack: [20, 13, 89, 90]
28
Queue Interface

➢ The Queue interface of the Java collections framework provides the functionality of the queue
data structure. It extends the Collection interface.
➢ Since the Queue is an interface, we cannot provide the direct implementation of it.
➢ To use the functionalities of Queue, we need to use classes that implement it:
How to use Queue?
➢ We must import java.util.Queue

29
Queue Interface

30
Queue Interface Example

31
Set Interface

▪ Set also extends Collection, but it prohibits duplicate items (this is what
defines a Set).
▪ No new methods are introduced; specifically, none for index-based
operations (elements of Sets are not ordered).
▪ More formally, sets contain no pair of elements e1 and e2 such that
e1.equals(e2), and at most one null element.
▪ Java has two implementations:
➢ HashSet
➢ TreeSet

32
Using Sets to find duplicate elements
import java.util.*;
public class FindDups
{
public static void main(String[] args)
{
Set<String> s = new HashSet<String>();
for (String a : args)
if (!s.add(a))
System.out.println("Duplicate detected: " + a);
System.out.println(s.size() + " distinct words: " + s);
}}
33
HashSets and hash tables
▪ Lists allow for ordered elements but searching them is very slow.

▪ Can speed up search tremendously if you don’t care about ordering.

▪ Hash tables let you do this. Drawback is that you have no control over how elements are ordered.

▪ hashCode() computes integer (quickly) which corresponds to position in hash table.

▪ Independent of other objects in table.

HashSet Class
▪ Hashing can be used to implement several important data structures.

▪ Simplest of these is HashSet.

▪ add elements with add(Object) method

▪ contains(Object) is redefined to first look for duplicates.

▪ if duplicate exists, Object is not added. 34


Prog. 10a. Develop a java program to implement and perform all the operations in
List, Set Interface.

import java.util.ArrayList; // Accessing elements using for-each loop


System.out.println("List Elements (using for-each
import java.util.HashSet; loop):");
import java.util.List; for (String element : myList) {
System.out.println(element);
import java.util.Set; }
public class ListSetExample {
// Set Example
public static void main(String[] args) { Set<String> mySet = new HashSet<>();
// List Example
// Adding elements to the set
List<String> myList = new ArrayList<>(); mySet.add("Apple");
// Adding elements to the list mySet.add("Banana");
mySet.add("Orange");
myList.add("Java"); mySet.add("Apple"); // Duplicates not allowed.
myList.add("Python");
System.out.println("\nSet Elements: " + mySet);
myList.add("C++"); // Accessing elements using for-each loop
myList.add("Java"); // Duplicates allowed in List System.out.println("Set Elements (using for-each
loop):");
System.out.println("List Elements: " + myList); for (String element : mySet) {
System.out.println(element);
} 35
Prog. 10a. Cont..
// Common operations
Output:
System.out.println("\nCommon Operations:");
List Elements: [Java, Python, C++, Java]
// Check if an element exists in the List
List Elements (using for-each loop):Java
System.out.println("Does myList contain 'Java'? "
Python
+ myList.contains("Java"));
C++
// Remove an element from the List
Java
myList.remove("C++");
Set Elements: [Apple, Orange, Banana]
System.out.println("List after removing 'C++': " +
Set Elements (using for-each loop):
myList);
Apple
// Check if an element exists in the Set
Orange
System.out.println("Does mySet contain 'Apple'? "
Banana
+ mySet.contains("Apple"));
Common Operations:
// Remove an element from the Set
Does myList contain 'Java'? true
mySet.remove("Banana");
List after removing 'C++': [Java, Python, Java]
System.out.println("Set after removing 'Banana': "
Does mySet contain 'Apple'? true
+ mySet);
Set after removing 'Banana': [Apple, Orange]
}} 36
Maps
▪ Maps are like collections but are represented by an entirely different class hierarchy.
Map<String, Integer> myMap = new HashMap<>();
▪ myMap.put("One", 1);
▪ myMap.put("Two", 2);
▪ Maps store objects by key/value pairs:
▪ map.add(“1234”, “Andrew”);
▪ i.e., Object Andrew is stored by Object key 1234
▪ Keys may not be duplicated.
▪ Each key may map to only one value.
▪ Methods can be broken down into three groups:
▪ querying
▪ altering
▪ obtaining different views

37
Map methods
▪ Here is a list of the Map methods:

Method Description
To remove all the elements or mappings from a specified Map
void clear()
collection.
- boolean To check whether a particular key is being mapped into the
containsKey(Object) Map or not
boolean To check whether a particular value is being mapped by a
containsValue(Object) single or more than one key in the Map
To create a set out of the same elements contained in the map.
Set entrySet() It basically returns a set view of the map, or we can create a
new set and store the map elements into them.
This method is used to retrieve or fetch the value mapped by a
boolean get(Object)
particular key mentioned in the parameter.
This method is used to check if a map is having any entry for
boolean isEmpty()
key and value pairs.
This method is used in Map Interface to return a Set view of
Set keySet()
the keys contained in this map.

38
Map methods (Cont..)

Method Description
Object put(Object, This method is used to associate the specified value with the
Object) specified key in this map.
void putall(Map) To copy all the mappings from the specified map to this map.
Used to remove the mapping for a key from this map if it is
Object remove(Object)
present in the map.
This method is used to return the number of key/value pairs
int size()
available in the map.

39
Prog. 10b. Develop a java program to implement and perform all the operations in
Map interface.

import java.util.HashMap;
import java.util.Map; // Accessing values using keys

import java.util.Set; String key = "Two";

public class MapExample { System.out.println("Value for key '" + key + "': " +

public static void main(String[] args) { myMap.get(key));

// Creating a Map // Checking if a key exists

Map<String, Integer> myMap = new HashMap<>(); System.out.println("Does map contain key 'Five'?

// Adding key-value pairs to the map " + myMap.containsKey("Five"));

myMap.put("One", 1); // Checking if a value exists

myMap.put("Two", 2); System.out.println("Does map contain value 3? "

myMap.put("Three", 3); + myMap.containsValue(3));

myMap.put("Four", 4); // Removing a key-value pair

// Displaying the map myMap.remove("Three");

System.out.println("Map Elements: " + myMap); System.out.println("Map after removing key


'Three': " + myMap);
40
Prog. 10b. (Cont..)

// Iterating through the keys


System.out.println("Keys in the map:"); Output:

Set<String> keys = myMap.keySet(); Map Elements: {One=1, Four=4, Two=2, Three=3}

for (String k : keys) { Value for key 'Two': 2

System.out.println(k); Does map contain key 'Five'? false

} Does map contain value 3? true

// Iterating through the key-value pairs Map after removing key 'Three': {One=1, Four=4,

System.out.println("Key-Value pairs in the map:"); Two=2}

for (Map.Entry<String, Integer> entry : Keys in the map:

myMap.entrySet()) { One

System.out.println(entry.getKey() + ": " + Four

entry.getValue()); Two

} } } Key-Value pairs in the map:


One: 1Four: 4Two: 2

41
THANK YOU

42

You might also like