0% found this document useful (0 votes)
2 views34 pages

Unit 3

The document covers Java exception handling, including the hierarchy of exceptions, the differences between checked and unchecked exceptions, and the usage of keywords like try, catch, throw, throws, and finally. It also discusses multithreading, highlighting the differences between processes and threads, the thread life cycle, and inter-thread communication. Additionally, it explains custom exceptions and provides examples of exception handling in Java.

Uploaded by

abhishek ch
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)
2 views34 pages

Unit 3

The document covers Java exception handling, including the hierarchy of exceptions, the differences between checked and unchecked exceptions, and the usage of keywords like try, catch, throw, throws, and finally. It also discusses multithreading, highlighting the differences between processes and threads, the thread life cycle, and inter-thread communication. Additionally, it explains custom exceptions and provides examples of exception handling in Java.

Uploaded by

abhishek ch
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/ 34

JAVA-UNIT-3

Exception handling-Benefits of exception handling, exception


hierarchy, the classification of exceptions - checked exceptions
and unchecked exceptions, usage of try, catch, throw, throws and
finally, creating own exception subclasses-custom exceptions.
Multithreading – Differences between multiple processes and
multiple threads, thread life cycle, creating threads, interrupting
threads, thread priorities, synchronizing threads, inter-thread
communication, producer consumer problem.

1. Exception in Java
An exception is an unexpected event that occurs during program execution.
It affects the flow of the program instructions which can cause the program to
terminate abnormally.
It is an object which is thrown at runtime.

Hierarchy of Java Exception classes


Types of Java Exceptions

Exceptions can be categorized into two ways:

1. Built-in Exceptions
1. Checked Exceptions
2. Unchecked Exceptions
2. User-Defined Exceptions / Custom Exceptions

1. Built-in Exceptions
There are 2 types.

1. Checked Exceptions

Checked exceptions are called compile-time exceptions because these


exceptions are checked at compile-time by the compiler. The compiler ensures
whether the programmer handles the exception or not. The programmer should
have to handle the exception otherwise the system has shown a compilation
error.
2. Unchecked Exceptions

The unchecked exceptions are just opposite to the checked exceptions. The
compiler will not check these exceptions at compile time. In simple words, if a
program throws an unchecked exception, and even if we didn't handle or declare
it, the program would not give a compilation error. Usually, it occurs when the
user provides bad data during the interaction with the program.

2. User-Defined Exceptions / Custom Exceptions

In Java, we can create our own exceptions that are derived classes of the
Exception class. Creating our own Exception is known as custom exception or
user-defined exception.

Basically, Java custom exceptions are used to customize the exception


according to user need.

Using the custom exception, we can have your own exception and message.
Here, we have passed a string to the constructor of superclass i.e. Exception
class that can be obtained using getMessage() method on the object we have
created.

2. Exception Handling Mechanism in java:


Exception Handling in Java is one of the effective means to handle the runtime
errors so that the regular flow of the application can be preserved.

Java Exception Handling is a mechanism to handle runtime errors such as


ClassNotFoundException, IOException, SQLException, RemoteException,
etc.

Exception Keywords in JAVA programming

Java provides five keywords that are used to handle the exception.

Keyword Description
try The "try" keyword is used to specify a block where we should place an
exception code. It means we can't use try block alone. The try block
must be followed by either catch or finally.

catch The "catch" block is used to handle the exception. It must be preceded
by try block which means we can't use catch block alone. It can be
followed by finally block later.

finally The "finally" block is used to execute the necessary code of the
program. It is executed whether an exception is handled or not.

throw The "throw" keyword is used to throw an exception.

throws The "throws" keyword is used to declare exceptions. It specifies that


there may occur an exception in the method. It doesn't throw an
exception. It is always used with method signature.

1. try and catch blocks

The try statement allows you to define a block of code to be tested for errors
while it is being executed.

The catch statement allows you to define a block of code to be executed, if an


error occurs in the try block.

The try and catch keywords come in pair.


Syntax of try and catch blocks

try {

// Block of code to try

catch(Exception e) {

// Block of code to handle errors

Examples using try and catch blocks

Example 1: Arithmetic exception


Class: Java.lang.ArithmeticException
This is a built-in-class present in java.lang package. This exception occurs when
an integer is divided by zero.

class Example1
{
public static void main(String args[])
{
try{
int num1=30, num2=0;
int output=num1/num2;
System.out.println ("Result: "+output);
}
catch(ArithmeticException e){
System.out.println ("You Shouldn't divide a number by zero");
}
}
}
Output of above program:
You Shouldn't divide a number by zero
Explanation: In the above example I’ve divided an integer by a zero and
because of this ArithmeticException is thrown.

Example 2: ArrayIndexOutOfBounds Exception


Class: Java.lang.ArrayIndexOutOfBoundsException
This exception occurs when you try to access the array index which does not
exist.
For example, If array is having only 5 elements and we are trying to display 7th
element then it would throw this exception.
class ExceptionDemo2
{
public static void main(String args[])
{
try{
int a[]=new int[10];
//Array has only 10 elements
a[11] = 9;
}
catch(ArrayIndexOutOfBoundsException e){
System.out.println ("ArrayIndexOutOfBounds");
}
}
}

Output:
ArrayIndexOutOfBounds
In the above example the array is initialized to store only 10 elements indexes 0
to 9. Since we are try to access element of index 11, the program is throwing
this exception.

Example 3: NumberFormat Exception


Class: Java.lang.NumberFormatException
This exception occurs when a string is parsed to any numeric variable.
For example, the statement int num=Integer.parseInt ("XYZ"); would throw
NumberFormatException because String “XYZ” cannot be parsed to int.
class ExceptionDemo3
{
public static void main(String args[])
{
try{
int num=Integer.parseInt ("XYZ") ;
System.out.println(num);
}catch(NumberFormatException e){
System.out.println("Number format exception occurred");
}
}
}
Output:
Number format exception occurred

Example 4: StringIndexOutOfBound Exception


Class: Java.lang.StringIndexOutOfBoundsException
An object of this class gets created whenever an index is invoked of a string,
which is not in the range.
Each character of a string object is stored in a particular index starting from 0.
To get a character present in a particular index of a string we can use a method
charAt(int) of java.lang.String where int argument is the index.

E.g.
class ExceptionDemo4
{
public static void main(String args[])
{
try{
String str="beginnersbook";
System.out.println(str.length());;
char c = str.charAt(0);
c = str.charAt(40);
System.out.println(c);
}catch(StringIndexOutOfBoundsException e){
System.out.println("StringIndexOutOfBoundsException!!");
}
}
}
Output:
13
StringIndexOutOfBoundsException!!
Exception occurred because the referenced index was not present in the String.

Example 5: NullPointer Exception


Class: Java.lang.NullPointer Exception
An object of this class gets created whenever a member is invoked with a “null”
object.
class Exception2
{
public static void main(String args[])
{
try{
String str=null;
System.out.println (str.length());
}
catch(NullPointerException e){
System.out.println("NullPointerException..");
}
}
}

Output:
NullPointerException.

Here, length() is the function, which should be used on an object. However in


the above example String object str is null so it is not an object due to which
NullPointerException occurred.

2. finally block

Java finally block is always executed whether an exception is handled or not.


Therefore, it contains all the necessary statements that need to be printed
regardless of the exception occur or not.

The finally block follows the try-catch block.

Syntax of finally block

try {
//Statements that may cause an exception
}
catch {
//Handling exception
}
finally {

//Statements to be executed

Example using finally block


Here you can see that the exception occurred in try block which has been
handled in catch block, after that finally block got executed.

class Example
{
public static void main(String args[]) {
try{
int num=121/0;
System.out.println(num);
}
catch(ArithmeticException e){
System.out.println("Number should not be divided by zero");
}
/* Finally block will always execute
* even if there is no exception in try block
*/
finally{
System.out.println("This is finally block");
}
System.out.println("Out of try-catch-finally");
}
}
Output:
Number should not be divided by zero
This is finally block

Out of try-catch-finally

4. throw keyword

The Java throw keyword is used to throw an exception explicitly.

In Java, an exception allows us to write good quality codes where the errors are
checked at the compile time instead of runtime.

We specify the exception object which is to be thrown. The Exception has some
message with it that provides the error description.

We can throw either checked or unchecked exceptions in Java by throw


keyword.

Syntax of throw keyword:

throw new exception_class("error message");

Example of throw keyword

/* In this program we are checking the Student age


* if the student age<12 and weight <40 then our program
* should return that the student is not eligible for registration.
*/
public class ThrowExample {
static void checkEligibilty(int stuage, int stuweight){
if(stuage<12 && stuweight<40) {
throw new ArithmeticException("Student is not eligible for registration");
}
else {
System.out.println("Student Entry is Valid!!");
}
}
public static void main(String args[]){
System.out.println("Welcome to the Registration process!!");
checkEligibilty(10, 39);
System.out.println("Have a nice day..");
}
}

Output:
Welcome to the Registration process!!Exception in thread "main"

java.lang.ArithmeticException: Student is not eligible for registration

5. throws keyword

The Java throws keyword is used to declare an exception. It gives an


information to the programmer that there may occur an exception.

So, it is better for the programmer to provide the exception handling code so
that the normal flow of the program can be maintained.

Exception Handling is mainly used to handle the checked exceptions. If there


occurs any unchecked exception such as NullPointerException, it is
programmers' fault that he is not checking the code before it being used.

Syntax of Java throws

return_type method_name() throws exception_class_name{

//method code

Example of throws keyword

In this example the method myMethod() is throwing two checked exceptions


so we have declared these exceptions in the method signature using throws
Keyword. If we do not declare these exceptions then the program will throw a
compilation error.
import java.io.*;
class ThrowExample {
void myMethod(int num)throws IOException, ClassNotFoundException{
if(num==1)
throw new IOException("IOException Occurred");
else
throw new ClassNotFoundException("ClassNotFoundException");
}
}
public class Example1{
public static void main(String args[]){
try{
ThrowExample obj=new ThrowExample();
obj.myMethod(1);
}catch(Exception ex){
System.out.println(ex);
}
}
}

Output:
java.io.IOException: IOException Occurred
3. User-Defined Exceptions / Custom Exceptions / Creating own
exception subclasses

In Java, we can create our own exceptions that are derived classes of the
Exception class. Creating our own Exception is known as custom exception or
user-defined exception.

Basically, Java custom exceptions are used to customize the exception


according to user need.

Using the custom exception, we can have your own exception and message.
Here, we have passed a string to the constructor of superclass i.e. Exception
class that can be obtained using getMessage() method on the object we have
created.

Example Program to Create own exception subclasses

class InvalidAgeException extends Exception


{
public InvalidAgeException (String str)
{
// calling the constructor of parent Exception
super(str);
}
}

// class that uses custom exception InvalidAgeException


public class Custom
{

// method to check the age


static void validate (int age) throws InvalidAgeException{
if(age < 18){
// throw an object of user defined exception
throw new InvalidAgeException("age is not valid to vote");
}
else {
System.out.println("welcome to vote");
}
}

// main method
public static void main(String args[])
{
try
{
// calling the method
validate(13);
}
catch (InvalidAgeException ex)
{
System.out.println("Caught the exception");

// printing the message from InvalidAgeException object


System.out.println("Exception occured: " + ex);
}
System.out.println("rest of the code...");
}
}
4. Difference between final ,finally,finalize keywords

S. Key final finally finalize


No.

1. Definition final is the finally is the finalize is the method in


keyword and block in Java Java which is used to
access modifier Exception perform clean up
which is used to Handling to processing just before
apply execute the object is garbage
restrictions on a important code collected.
class, method or whether the
variable. exception occurs
or not.

2. Applicabl Final keyword is Finally block is finalize() method is


e to used with the always related to used with the objects.
classes, methods the try and catch
and variables. block in
exception
handling.

3. Functiona (1) Once (1) finally block finalize method


lity declared, final runs the performs the cleaning
variable important code activities with respect
becomes even if exception to the object before its
constant and occurs or not. destruction.
cannot be (2) finally block
modified. cleans up all the
(2) final method resources used in
cannot be try block
overridden by
sub class.
(3) final class
cannot be
inherited.
4. Execution Final method is Finally block is finalize method is
executed only executed as soon executed just before the
when we call it. as the try-catch object is destroyed.
block is
executed.

It's execution is
not dependant on
the exception.

5. Difference between throw and throws keywords


throw throws
A throw is used to throw an exception A throws to declare one or more
explicitly exceptions, separated by commas.
Multiple can be thrown using
Can throw a single exception using throw Throws
Signature method is used with
This keyword is used in the method keyword throws
To raise an exception throws
keyword followed by the class
Only unchecked exceptions propagated using name and checked exception can be
throw keyword. propagated.
Throw keyword is followed by the instance Throws keyword is followed by the
variable exception class

6. Difference between Checked Exceptions and unchecked


Exceptions

Checked Exceptions Unchecked Exceptions


1.Checked exceptions occur at
compile time. 1.Unchecked exceptions occur at runtime.
2.The compiler checks a checked 2.The compiler does not check these types of
exception. exceptions.
3.These types of exceptions can be 3.These types of exceptions cannot be a catch
handled at the time of compilation. or handle at the time of compilation
4.They are the sub-class of the 4.They are runtime exceptions and hence are
exception class. not a part of the Exception class.
5.Here, the JVM needs the exception 5.Here, the JVM does not require the exception
to catch and handle. to catch and handle.
Examples of Checked exceptions: Examples of Unchecked Exceptions:
File Not Found Exception No Such Element Exception
No Such Field Exception Undeclared Throwable Exception
Interrupted Exception Empty Stack Exception
No Such Method Exception Arithmetic Exception
Class Not Found Exception Null Pointer Exception
Array Index Out of Bounds Exception
Security Exception

7. Multithreading

Multithreading in java is a process of executing multiple threads


simultaneously.

Thread

Thread is basically a lightweight sub-process, a smallest unit of processing.


Multiprocessing and multithreading, both are used to achieve multitasking.

But we use multithreading than multiprocessing because threads share a


common memory area. They don't allocate separate memory area so saves
memory, and context-switching between the threads takes less time than
process.

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 you can
perform multiple operations at the same time.

2) You can perform many operations together, so it saves time.

3) Threads are independent, so it doesn't affect other threads if an exception


occurs in a single thread.
Multitasking

Multitasking is a process of executing multiple tasks simultaneously. We use


multitasking to utilize the CPU.

Multitasking can be achieved in two ways:

1. Process-based Multitasking (Multiprocessing)


2. Thread-based Multitasking (Multithreading)

8. Multiprocessing Vs Multithreading

S.No. Multiprocessing Multithreading

While In Multithreading,
many threads are created of
In Multiprocessing, CPUs are added
1. a single process for
for increasing computing power.
increasing computing
power.

While in multithreading,
In Multiprocessing, Many processes
2. many threads of a process
are executed simultaneously.
are executed simultaneously.

Multiprocessing are classified While Multithreading is not


3.
into Symmetric and Asymmetric. classified in any categories.

While in Multithreading,
In Multiprocessing, Process creation
4. process creation is according
is a time-consuming process.
to economical.

5. While in Multithreading, a
In Multiprocessing, every process
common address space is
S.No. Multiprocessing Multithreading

owned a separate address space. shared by all the threads.

9. Life cycle of a Thread (Thread States)

1. NEW – a newly created thread that has not yet started the execution.
2. RUNNABLE – either running or ready for execution but it's waiting for
resource allocation.
3. BLOCKED – waiting to acquire a monitor lock to enter or re-enter a
synchronized block/method.
4. WAITING – waiting for some other thread to perform a particular action
without any time limit.
5. TIMED_WAITING – waiting for some other thread to perform a specific
action for a specified period.
6. TERMINATED – has completed its execution.
10. Creating threads:

The java programming language provides two methods to create threads, and
they are listed below.

1. Using Thread class (by extending Thread class)

2. Uisng Runnable interface (by implementing Runnable interface)

1. Extending Thread class


The java contains a built-in class Thread inside the java.lang package. The
Thread class contains all the methods that are related to the threads.

To create a thread using Thread class, follow the steps given below.
Step-1: Create a class as a child of Thread class. That means, create a class that
extends Thread class.

Step-2: Override the run( ) method with the code that is to be executed by the
thread. The run( ) method must be public while overriding.

Step-3: Create the object of the newly created class in the main( ) method.

Step-4: Call the start( ) method on the object created in the above step.

Example Program: Java Thread Example by extending Thread class

class Multi extends Thread{


public void run(){
System.out.println("thread is running...");
}
public static void main(String args[]){
Multi t1=new Multi();
t1.start();
}
}

Output:
Thread is running

2. Uisng Runnable interface (by implementing Runnable interface)

The java contains a built-in interface Runnable inside the java.lang package.
The Runnable interface implemented by the Thread class that contains all the
methods that are related to the threads.
To create a thread using Runnable interface, follow the steps given below.

Step-1: Create a class that implements Runnable interface.

Step-2: Override the run( ) method with the code that is to be executed by the
thread. The run( ) method must be public while overriding.

Step-3: Create the object of the newly created class in the main( ) method.
Step-4: Create the Thread class object by passing above created object as
parameter to the Thread class constructor.

Step-5: Call the start( ) method on the Thread class object created in the above
step.

Example Program: Java Thread Example by implementing Runnable


interface

class Multi implements Runnable{


public void run(){
System.out.println("thread is running...");
}
public static void main(String args[]){
Multi m1=new Multi();
Thread t1 =new Thread(m1); // Using the constructor Thread(Runnable r)
t1.start();
}
}

Output:
Thread is running
11. Commonly used methods of Thread class
1. public void run(): is used to perform action for a thread.
2. public void start(): starts the execution of the thread.JVM calls the run()
method on the thread.
3. public void sleep(long miliseconds): Causes the currently executing
thread to sleep (temporarily cease execution) for the specified number of
milliseconds.
4. public void join(): waits for a thread to die.
5. public void join(long miliseconds): waits for a thread to die for the
specified miliseconds.
6. public int getPriority(): returns the priority of the thread.
7. public int setPriority(int priority): changes the priority of the thread.
8. public String getName(): returns the name of the thread.
9. public void setName(String name): changes the name of the thread.
10.public Thread currentThread(): returns the reference of currently
executing thread.
11.public int getId(): returns the id of the thread.
12.public Thread.State getState(): returns the state of the thread.
13.public boolean isAlive(): tests if the thread is alive.
14.public void yield(): causes the currently executing thread object to
temporarily pause and allow other threads to execute.
15.public void suspend(): is used to suspend the thread(depricated).
16.public void resume(): is used to resume the suspended thread(depricated).
17.public void stop(): is used to stop the thread(depricated).
18.public boolean isDaemon(): tests if the thread is a daemon thread.
19.public void setDaemon(boolean b): marks the thread as daemon or user
thread.
20.public void interrupt(): interrupts the thread.
21.public boolean isInterrupted(): tests if the thread has been interrupted.
22.public static boolean interrupted(): tests if the current thread has been
interrupted.

12. Interrupting a Thread


If any thread is in sleeping or waiting state (i.e. sleep() or wait() is invoked),
calling the interrupt() method on the thread, breaks out the sleeping or waiting
state throwing InterruptedException.

If the thread is not in the sleeping or waiting state, calling the interrupt() method
performs normal behaviour and doesn't interrupt the thread but sets the interrupt
flag to true.

3 methods provided by the Thread class for interrupting a thread

1. public void interrupt()


2. public static boolean interrupted()
3. public boolean isInterrupted()

Example of interrupting a thread that stops working

In this example, after interrupting the thread, we are propagating it, so it will
stop working. If we don't want to stop the thread, we can handle it where sleep()
or wait() method is invoked. Let's first see the example where we are
propagating the exception.

class TestInterruptingThread1 extends Thread{


public void run(){
try{
Thread.sleep(1000);
System.out.println("task");
}catch(InterruptedException e){
throw new RuntimeException("Thread interrupted..."+e);
}
}

public static void main(String args[]){


TestInterruptingThread1 t1=new TestInterruptingThread1();
t1.start();
try{
t1.interrupt();
}catch(Exception e){System.out.println("Exception handled "+e);}

}
}

Output:
Exception in thread-0
java.lang.RuntimeException: Thread interrupted...
java.lang.InterruptedException: sleep interrupted
at A.run(A.java:7)

13. JAVA Thread Priority

In a java programming language, every thread has a property called priority.


Most of the scheduling algorithms use the thread priority to schedule the
execution sequence. In java, the thread priority range from 1 to 10. Priority 1 is
considered as the lowest priority, and priority 10 is considered as the highest
priority. The thread with more priority allocates the processor first.

The java programming language Thread class provides two methods


setPriority(int), and getPriority( ) to handle thread priorities.

The Thread class also contains three constants that are used to set the thread
priority, and they are listed below.

MAX_PRIORITY - It has the value 10 and indicates highest priority.

NORM_PRIORITY - It has the value 5 and indicates normal priority.

MIN_PRIORITY - It has the value 1 and indicates lowest priority.

Example of priority of a Thread


// Importing the required classes

import java.lang.*;

public class ThreadPriorityExample extends Thread

// Method 1

// Whenever the start() method is called by a thread

// the run() method is invoked

public void run()

// the print statement

System.out.println("Inside the run() method");

// the main method

public static void main(String argvs[])

// Creating threads with the help of ThreadPriorityExample class

ThreadPriorityExample th1 = new ThreadPriorityExample();

ThreadPriorityExample th2 = new ThreadPriorityExample();

ThreadPriorityExample th3 = new ThreadPriorityExample();

// We did not mention the priority of the thread.

// Therefore, the priorities of the thread is 5, the default value

// 1st Thread

// Displaying the priority of the thread

// using the getPriority() method


System.out.println("Priority of the thread th1 is : " + th1.getPriority());

// 2nd Thread

// Display the priority of the thread

System.out.println("Priority of the thread th2 is : " + th2.getPriority());

// 3rd Thread

// // Display the priority of the thread

System.out.println("Priority of the thread th3 is : " + th3.getPriority());

// Setting priorities of above threads by

// passing integer arguments

th1.setPriority(6);

th2.setPriority(3);

th3.setPriority(9);

// 6

System.out.println("Priority of the thread th1 is : " + th1.getPriority());

// 3

System.out.println("Priority of the thread th2 is : " + th2.getPriority());

// 9

System.out.println("Priority of the thread th3 is : " + th3.getPriority());

// Main thread

// Displaying name of the currently executing thread

System.out.println("Currently Executing The Thread : " +


Thread.currentThread().getName());

System.out.println("Priority of the main thread is : " +


Thread.currentThread().getPriority());

// Priority of the main thread is 10 now


Thread.currentThread().setPriority(10);

System.out.println("Priority of the main thread is : " +


Thread.currentThread().getPriority());

Output:
Priority of the thread th1 is : 5
Priority of the thread th2 is : 5
Priority of the thread th2 is : 5
Priority of the thread th1 is : 6
Priority of the thread th2 is : 3
Priority of the thread th3 is : 9
Currently Executing The Thread : main
Priority of the main thread is : 5
Priority of the main thread is : 10

14. Synchronization in Java


Synchronization in java is the capability to control the access of multiple
threads to any shared resource.

Java Synchronization is better option where we want to allow only one thread to
access the shared resource.

In the Multithreading concept, multiple threads try to access the shared


resources at a time to produce inconsistent results.

Types of Synchronization

Synchronization is classified into two types

1. Process Synchronization
2. Thread Synchronization
1. Process Synchronization

The process is nothing but a program under execution. It runs independently


isolated from another process. The resources like memory and CPU time, etc.
are allocated to the process by the operation System.

2. Thread Synchronization: Inter Thread Communication in


JAVA

Inter-thread communication or Co-operation is all about allowing synchronized


threads to communicate with each other.

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


paused running in its critical section and another thread is allowed to enter (or
lock) in the same critical section to be executed.

It is implemented by following methods of Object class:

1. wait()
2. notify()
3. 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.

Syntax:
public final void notify()

3) notifyAll() method

Wakes up all threads that are waiting on this object's monitor.

Syntax:

public final void notifyAll()

Producer-Consumer solution using threads in Java

In computing, the producer-consumer problem (also known as the bounded-


buffer problem) is a classic example of a multi-process synchronization
problem.

Producer and Consumer are two separate processes. Both processes share a
common buffer or queue. The producer continuously produces certain data and
pushes it onto the buffer, whereas the consumer consumes those data from the
buffer.

A diagram showing this simple scenario:

 Both producer and consumer may try to update the queue at the same
time. This could lead to data loss or inconsistencies.
 Producers might be slower than consumers. In such cases, the consumer
would process elements fast and wait.
 In some cases, the consumer can be slower than a producer. This situation
leads to a queue overflow issue.
 Problem
To make sure that the producer won’t try to add data into the buffer if
it’s full and that the consumer won’t try to remove data from an empty
buffer.

 Solution
The producer is to either go to sleep or discard data if the buffer is full.
The next time the consumer removes an item from the buffer, it notifies
the producer, who starts to fill the buffer again. In the same way, the
consumer can go to sleep if it finds the buffer to be empty. The next
time the producer puts data into the buffer, it wakes up the sleeping
consumer.
An inadequate solution could result in a deadlock where both processes
are waiting to be awakened.

Example Program
// Java program to implement solution of producer
// consumer problem.

import java.util.LinkedList;

public class Threadexample {


public static void main(String[] args)
throws InterruptedException
{
// Object of a class that has both produce()
// and consume() methods
final PC pc = new PC();

// Create producer thread


Thread t1 = new Thread(new Runnable() {
@Override
public void run()
{
try {
pc.produce();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
});

// Create consumer thread


Thread t2 = new Thread(new Runnable() {
@Override
public void run()
{
try {
pc.consume();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
});

// Start both threads


t1.start();
t2.start();

// t1 finishes before t2
t1.join();
t2.join();
}

// This class has a list, producer (adds items to list


// and consumer (removes items).
public static class PC {

// Create a list shared by producer and consumer


// Size of list is 2.
LinkedList<Integer> list = new LinkedList<>();
int capacity = 2;

// Function called by producer thread


public void produce() throws InterruptedException
{
int value = 0;
while (true) {
synchronized (this)
{
// producer thread waits while list
// is full
while (list.size() == capacity)
wait();

System.out.println("Producer produced-"
+ value);

// to insert the jobs in the list


list.add(value++);

// notifies the consumer thread that


// now it can start consuming
notify();

// makes the working of program easier


// to understand
Thread.sleep(1000);
}
}
}

// Function called by consumer thread


public void consume() throws InterruptedException
{
while (true) {
synchronized (this)
{
// consumer thread waits while list
// is empty
while (list.size() == 0)
wait();

// to retrieve the first job in the list


int val = list.removeFirst();

System.out.println("Consumer consumed-"
+ val);

// Wake up producer thread


notify();

// and sleep
Thread.sleep(1000);
}
}
}
}
}

Output:
Producer produced-0
Producer produced-1
Consumer consumed-0
Consumer consumed-1
Producer produced-2

You might also like