Unit-4 Java
Unit-4 Java
Errors in Java :
• Errors in Java occur when a programmer violates the rules of Java programming language.
It may produce incorrect output or may terminate the execution of the program abnormally.
• For example, if you use the right parenthesis in a Java program where a right brace is needed,
you have made a syntax error. You have violated the rules of Java language.
• Therefore, it is important to detect and fix properly all errors occurring in a program so that
the program will not terminate during execution.
2. Runtime errors
3. Logical errors
• These syntactical problems may be missing semicolons, missing brackets, misspelled keywords,
use of undeclared variables, class not found, missing double-quote in Strings, and so on. These
problems occurring in a program are called syntax errors in Java.
•Since all syntax errors are detected by Java compiler, therefore, these errors are also known as
compile time errors in Java.
•When Java compiler finds syntax errors in a program, it prevents the code from compile
successfully and will not create a class file until errors are not corrected. An error message will be
displayed on the console screen.
•These errors must be removed by debugging before successfully compile and run the program.
• Such a program that contains runtime errors may produce wrong results due to wrong logic or
terminate the program. These runtime errors are usually known as exceptions.
For example, if a user inputs a value of string type in a program but the computer is expecting an
integer value, a runtime error will be generated.
4. Passing an argument that is not in a valid range or valid value for a method.
To handle these kinds of errors during the runtime, we use exception handling technique in java
program.
Let's take different kinds of example programs to understand better. In this program, we will
divide an integer number by zero. Java compiler cannot detect it.
The above program is syntactically correct. There is no syntax error and therefore, does not cause
any problem during compilation. While executing, runtime error occurred that is not detected by
compiler.
The error is detected by JVM only in runtime. Default exception handler displays an error
message and terminates the program abnormally without executing further statements in the
program.
Let's take an example program where we will try to retrieve a value from an array using an index
that is out of range of the array.
Accessing ValueOutOfRangeError.java:9)
• Logical errors are not detected either by Java compiler or JVM (Java runtime system). The
programmer is entirely responsible for them. They can be detected by application testers when
they compare the actual result with its expected result.
For example, a programmer wants to print even numbers from an array but he uses division (/)
operator instead of modulus (%) operator to get the remainder of each number. Due to which
he got the wrong results.
As you can see the program is successfully compiled and executed but the programmer got the
wrong output due to logical errors in the program.
A software engineer in a company also commits several errors while designing the project or
developing code.
These errors in a program are also called bugs and the process of fixing these bugs is called
debugging.
One of the key benefits of exception handling is that it ensures the continuity of the program.
Without proper exception handling, an unhandled exception would cause the program to
terminate abruptly, which can lead to data loss & other issues.
Exception handling allows for the program to anticipate and recover from errors, thus making
the program more robust and resistant to unexpected conditions.
Proper exception handling also improves the readability & maintainability of the code. By
catching and handling exceptions, the program can provide clear error messages that accurately
describe the error and provide information on how to resolve the issue.
4. Allows for more Accurate Error Reporting
Exception handling allows the program to catch & report errors in a more accurate & detailed
manner.
Exception handling allows developers to quickly identify and resolve issues, reducing the amount
of time and resources required for debugging.
Exception handling can also improve the security of a program by preventing sensitive
information from being exposed in the event of an error. By catching and handling exceptions,
the program can prevent sensitive information, such as passwords.
Proper exception handling allows the program to anticipate and recover from errors, providing a
more stable user experience.
Exception handling enables the use of error-recovery mechanisms, such as retries or fallbacks,
which can improve the reliability and availability of the program.
Proper exception handling can also improve the scalability and performance of a program by
reducing the amount of unnecessary processing and resources consumption. By catching and
handling exceptions, the program can avoid performing unnecessary operations and releasing
resources that are no longer needed, reducing the overall load on the system and improving
performance.
2) Unchecked Exception:The classes that inherit the Runtime Exception are known as
unchecked exceptions.
For example, ArithmeticException, ArrayIndexOutOfBoundsException, at run time.
NullPointerException, etc.
Unchecked exceptions are not checked at compile-time, but they are checked at run time.
• If an exception occurs at the particular statement in the try block, the rest of the block code
will not execute. So, it is recommended not to keep the code in try block that will not throw an
exception.
try{
//code that may throw an exception
} catch (Exception_class _Name ref) { }
• Syntax of try-finally block
try{
//code that may throw an exception
}finally { }
Java catch block.
• Java catch block is used to handle the exception by declaring the type of exception within the
parameter. The declared exception must be the parent class exception (i.e., Exception) or the
generated exception type. However, the good approach is to declare the generated type of
exception.
• The catch block must be used after the try block only. You can use multiple catch block with a
single try block.
• The JVM firstly checks whether the exception is handled or not. If exception is not handled,
JVM provides a default exception handler that performs the following tasks:
b. Prints the stack trace (Hierarchy of methods where the exception occurred).
c. Causes the program to terminate.
• But if the application programmer handles the exception ,the normal flow of the application is
maintained, i.e., rest of the code is executed.
• Problem without exception handling : Let's try to understand the problem if we don't use a
try-catch block.
As displayed in the above example, the rest of the code is not executed fin such case, the rest of
the code statement is not printed).
There might be 100 lines of code after the exception. If the exception is handled, all the code
below the exception won't be executed.
Solution by exception handling:Let's see the solution of the above problem by a java try-catch
block.
As displayed in the above example, the rest of the code is executed, i.e., the rest of the code
statement is printed.
TryCatchExample3.java
• Java finally block is a block used to execute important code such as closing the connection, etc.
• 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.
Note: If you don't handle the exception, before terminating the program, JM executes finally
block (if any).
The purpose of finally block:
•Finally block in Java can be used to put "cleanup" code such as closing a file, closing connection,
etc.
Let's see the different cases where Java finally block can be used.
classTestFinallyBlock {
public static void main (String args []) {
try{
//below code do not throw any exception
int data=25/5;
System. out. println (data) ; }
//catch won't be executed
catch (NullPointerException e) {
System. out. println (e) ;
}
finally {
//executed regardless of exception occurred or not
System. out. println ("finally block is always executed") ;
System. out .println ("rest of the code...");
}}}
Output:
5
Case 2:When an exception occur but not handled by the catch block
Let's see the following example. Here, the code throws an exception however the catch block
cannot handle it. Despite this, the finally block is executed after the try block and then the
program terminates abnormally.
TestFinallyBlockl.java.
TestFinallyBlock2.java.
public class TestFinallyBlock2{
public static void main (String args[]) { try {
System. out .println ("Inside try block") ;
//below code throws divide by zero exception
int data=25/0;
System. out. println (data) ;
}
//handles the Arithmetic Exception / Divide by zero exception
catch (ArithmeticException e) {
System. out.println ("Exception handled") ;
System. out. println (e) ;
}
//executes regardless of exception occured or not
finally{
System. out.println ("finally block is always executed") ;
System. out.println("rest of the code...") ;
}}}
Output:
Inside try block
Exception handled
Java lang. ArithmeticException: / by zero
finally block is always executed
rest of the code...
Rule: For each try block there can be zero or more catch blocks, but only
one finally block.
Note: The finally block will not be executed if the program exists(either by calling System.exit()
or by causing a fatal error that causes the process to abort).
• We specify the exception object which is to be thrown. The Exception has some message with
it that provides the error description. These exceptions may be related to user inputs, server, etc.
• We can throw either checked or unchecked exceptions in Java by throw keyword. It is mainly
used to throw a custom exception.
• We can also define our own set of conditions and throw an exception explicitly using throw
keyword.
Where the Instance must be of type Throwable or subclass of Throu example, Exception is the
sub class of Throwable and the user-defined ex usually extend the Exception class.
In this example, we have created a method named validate() that accepts an integer as a
parameter. If the age is less than 18, we are throwing the Arithmetic Exception otherwise print a
message welcome to vote.
at Test Throw 1.validate (Test Throw1.java:8) at Test Throw 1. main (Test Throwl.java:18)
The above code throw an unchecked exception. Similarly, we can also throw unchecked and user
defined exceptions.
• 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.
//method code }
Only checked exception should be declared, because unchecked exception is under our control so
we can correct our code.
Java throws Example: Let's see the example of Java throws clause which describes that checked
exceptions can be propagated by throws keyword.
Testthrows1.java.
Case 2:We have declared the exception i.e. specified throws keyword with the method.
Testthrows2.java
import java.io.*;
class M{
void method () throws IOException{
throw new IOException ("device error") ;
} }
public class Testthrows2{
public static void main (String args []) { try {
M m=new M() ;
m. method () ;
catch (Exception e) {
System. out. println ("exception handled") ; }
System. out. println ("normal flow...");
}}
Output:
exception handled
normal flow...
Case 2: Declare Exception.
In case we declare the exception, if exception does not occur, the code willbe executed fine.
In case we declare the exception and the exception occurs, it will be thrown al runtime because
throws does not handle the exception.
import java.io.*;
class M{
void method () throws IOException {
System.out.println ("device operation performed") ;
}}
class Testthrows3 {
public static void main (String args []) throws IOException { // declare exception
M m-new M() ;
m. method () ;
System.out.println ("normal flow...");
}}
Output:
device operation performed
normal flow...
B) If exception occurs
Testthrows4. java
import java.io.*;
class M{
void method () throws IOException{
throw new IOException ("device error") ; } }
class Testthrows4{
public static void main (String args[]) throws IOException{// declare exception
M m=new M() ;
m.method () :
System.out.println ("normal flow...");
}}
Output:
Exception in thread "main" java.io. IOException: device error at M. method
(TestThrows4.java:4)
at TestThrows4.main(TestThrows4.java:10)
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.
• A try block can be followed by one or more a catch blocks. Each catch block must contain a
different exception handler. So if you have to perform different tasks at the occurrence of
different exceptions, use java multi catch block.
• At a time only one exception occurs and at a time only one catch blocks
• All catch blocks must be ordered from most specific to most general, i.e. catch for Arithmetic
Exception must come before catch for Exception.
Sometimes a situation may arise where a part of a block may cause one error and the
entire block itself may cause another error. In such cases, exception handlers have to be
nested.
Syntax:
NestedTryBlock.java
• In Java, exception is an event that occurs during the execution of a program and
disrupts the normal flow of the program's instructions.
• Bugs or errors that we don't want and restrict our program's normal execution of code
are referred to as exceptions.
• Built-in Exceptions
• User-Defined Exceptions
Built-in Exception:
• It can be categorized into two broad categories, i.e., checked exceptions and
unchecked exception.
Checked Exception:
• 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 sustem has
shown a compilation error.
CheckedExceptionExample.java.
import java.io.*;
classCheckedExceptionExample {
public static void main (String args []) {
FileInputStreamfile_data = null;
file_data = new FileInputStream("C: /Users/ajeet/OneDrive/Desktop/Hello.txt") ;
int m;
while ( (m = file_data. read () ) != -1) {
System. out print ( (char)m) ;
file_data.close () ;}}
Output:
error
usersajeet \OneDrive|Desktop\programs>-
Resolving the error:- We will use the try-catch block in the following way:
Exception. java.
import java.io.*;
class Exception{
public static void main (String args []) {
FileInputStream file_ data = null;
try {
file_data = new FileInputStream ("C: /Users/ajeet/OneDrive/Desktop/
programs/Hell. txt") ; }
catch (FileNotFoundExceptionfnfe){
System. out. println ("File Not Found!") ;}
int m;
try{
while ((m = file_data.read () ) != -1) {
System. out print ( (char)m) ;}
file data. close () ;}
catch (IOExceptionioe) {
System. outprintin("I/0 error occurred: "+ioe) ;}}
Output:
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.
Note: The RuntimeException class is able to resolve all the ur exceptions because of the
child-parent relationship.
UncheckedExceptionExamplel.java
classUncheckedExceptionExamplel {
public static void main (String args []){
int positive = 35;
int zero = 0;
int result = positive/zero;
//Give Unchecked Exception here.
System. outprintln (result) ;
}}
In the above program, we have divided 35 by 0. The code would be compiled
successfully, but it will throw an ArithmeticException error at runtime dividing a number
by 0 throws the divide by zero exception that is a l' exception.
Output:
ERROR!
Error: Division by zero!
UncheckedExceptionExample2.java
class UncheckedexceptionExample2 {
public static void main (String args[]){
intnum (] =(10,20, 30, 40,50, 60);
system. out-printin (num[7]) ;}}
Output:
In the above code, we are trying to get the element located at position 7, but the length
of the array is 6. The code compiles successfully, but throws the
ArrayIndexOutOfBoundsException at runtime.
4.8 DESCRIBE MULTITHREADING:
• Multithreading in Java is a process of executing multiple threads simultaneously.
• It doesn't block the user because threads are independent and you can perform
multiple operations at the same time.
The thread can exist in different states. Just because a thread's start () method has been
called, it doesn't mean that the thread has access to the CPU and can start executing
straight away. Several factors determine how it will process.
The life cycle of the thread in java is controlled by JVM. A thread goes through various
stages in its life cycle.
.Newborn
.Runnable
.Running
.Blocked
.Dead
New - A new thread begins its life cycle in the new state. It remains in this state until the
program starts the thread. It is also referred to as a born thread.
In simple words, a thread has been created, but it has not yet been started. A thread is
started by calling its start() method.
Runnable - The thread is in the runnable state after the invocation of the start| method,
but the thread scheduler has not selected it to be the running thread. A thread starts life
in the Ready-to-run state by calling the start method and waiting for its turn. The thread
scheduler decides which thread runs and for how long.
Running - When the thread starts executing, then the state is changed to a
"running" state. The scheduler selects one thread from the thread pool, and it starts
executing in the application.
Dead - This is the state when the thread is terminated. The thread is in a running state
and as soon as it is completed processing it is in a "dead state" Once a thread is in this
state, the thread cannot even run again.
This is the state when the thread is still alive but is currently not eligible to run.
occurs. A thread doesn't go directly to the running state from a non-runnable state but
transits first to the Ready-to-run state.
Here we are giving a simple example of the Thread life cycle. In this t we will create a
Java class where we will create a Thread, and then we some of its methods that
represents its life cycle.
In Java, one can get the current state of a thread using the Thread.getState() method. The
java .lang. Thread. State class of Java provides the constants ENUM to represent the state
of a thread. These constants are:
public static final Thread.State NEW : It represents the first state of a thread that is the
NEW state.
public static final Thread.State RUNNABLE : It represents the runnable state.It means a
thread is waiting in the queue to run.
public static final Thread.State BLOCKED : It represents the blocked state. In this state,
the thread is waiting to acquire a lock.
public static final Thread. State WAITING : It represents the waiting state. A thread will
go to this state when it invokes the Object.wait() method, or Thread.join() method with
no timeout. A thread in the waiting state is waiting for another thread to complete its
task.
public static final Thread.State TIMED _WAITING : It represents the timed waiting state.
The main difference between waiting and timed waiting is the time constraint. Waiting
has no time constraint, whereas timed waiting has the time constraint.
public static final Thread.State TERMINATED : It represents the final state of a thread
that is terminated or dead. A terminated thread means it has completed its execution.
Java Program for Demonstrating Thread States: The following Java program shows some
of the states of a thread defined above.
FileName: ThreadState.java:
// Starting thread t2
t2.start();
// Thread t2 is moved to the runnable state
System.out.println("The state of thread t2 after calling the method start() on it: " +
t2.getState());
try { // Moving the thread t1 to the state timed waiting
Thread.sleep(200);
} catch (InterruptedExceptionie) {
ie.printStackTrace(); }
// The state of thread t2 after invoking the method sleep() on it
System.out.println("The state of thread t2 after invoking the method sleep() on it: " +
t2.getState());
try {
// Waiting for thread t2 to complete its execution
t2.join();
} catch (InterruptedExceptionie) {
ie.printStackTrace();}
// The state of thread t2 when it has completed its execution
System.out.println("The state of thread t2 when it has completed its execution: " +
t2.getState());}}
Output:
The state of thread t1 after spawning it: NEW
The state of thread t1 after invoking the method start(): RUNNABLE
The state of thread t2 after spawning it: NEW
The state of thread t2 after calling the method start() on it: RUNNABLE
The state of thread t2 after invoking the method sleep() on it: TIMED_WAITING
The state of thread t2 when it has completed its execution: TERMINATED
4.10 EXPLAIN HOW TO CREATING SINGLE THREAD WITH EXAMPLE
PROGRAM :
1)Thread class:
Thread class provide constructors and methods to create imp perform operations Thread
dead. Thread class extends Object class and implements Runnable interface.
Thread ()
Thread (Runnable r)
public void start(): starts the execution of the thread.JVM calls the method on the thread.
public void sleep(long miliseconds): Causes the currently executing thre to sleep
(temporarily cease execution) for the specified number of milliseconds.
public void join(): waits for a thread to die.
public void join(long miliseconds): waits for a thread to die for the specified miliseconds.
public void yield(): causes the currently executing thread object to temporarily pause and
allow other threads to execute.
public void setDaemon (boolean b): marks the thread as daemon or userthread.
public static boolean interrupted (): tests if the current thread has been interrupted.
2)Runnable interface:
The Runnable interface should be implemented by any class whose instances are
intended to be executed by a thread. Runnable interface have only one method named
run ().
Starting a thread: The start method of Thread class is used to start a newlycreated thread.
It performs the following tasks:
When the thread gets a chance to execute, its target run() method will run.
Basically, when we need to perform several tasks at a time, we can create multiple
threads to perform multiple tasks in a program.
For example, to perform two tasks, we can create two threads and attach them to two
tasks. Hence, creating multiple threads in Java programming helps to perform more than
one task simultaneously.
Creating more than one thread to perform multiple taskscalled multithreading in Java. In
multiple threading programming, multiple threads are executing simultaneously that
improves the performance of CP because CPU is not idle if other threads are waiting to
get someresource
Multiple threads share the same address space in the heap memor Therefore, It is good to
create multiple threads to execute multiple tasrather than creating multiple processes.
Look at the below picture.
Benefits of Creating multiple threads in Java for Multitasking:
Let's create a Java program in which we will try to implement this realtime scenario.
Program code:
It is also possible to create two or more threads on a single object, Let's create a Java
program in which three threads will share the same object (same ron() method).
Program code:
3.In addition to this, the java virtual machine can also assign priority to threads or
explicitly given by the programmers. The range of values for the priority of a thread lies
between 1 and 10 (inclusive).
- MAX_PRIORITY The maximum priority that a thread has, whose default value is 10.
- NORM _ PRIORITY The default priority that a thread has, whose default value is 5.
5.The 'getPriority()' method in Java helps in returning the priority of the thread bound as
value to it.
6.The 'setPriority()' method changes the priority value of a given thread. It throws the
IllegalArgumentException when the thread priority is less than 1 or greater than 10.
Program code:
1.When we start two or more threads within a program, there may be a situation when
multiple threads try to access the same resource and finally they can produce unforeseen
result due to concurrency issues. For example, if multiple threads try to write within a
same file then they may corrupt the data because one of the threads can override data or
while one thread is opening the same file at the same time another thread might be
closing the same file.
2.So there is a need to synchronize the action of multiple threads and make sure that
only one thread can access the resource at a given point in time. This is implemented
using a concept called monitors.
3.Each object in Java is associated with a monitor, which a thread can lock or unlock.
Only one thread at a time may hold a lock on a monitor.
4.Java programming language provides a very handy way of creating threads and
synchronizing their task by using synchronized blocks.
Syntax:
synchronized(objectidentifier) {
Here is a simple example which may or may not print counter value in sequence and
every time we run it, it produces a different result based on CPU availability to a thread.
Program code
classPrintDemo {
public void printCount() {
try {
for (inti = 5; i> 0; i--) { System.out.println("Counter - " + i) }
} catch (Exception e) {
System.out.println("Thread interrupted.");}}
classThreadDemo extends Thread {
private Thread t;
private String threadName;
PrintDemoPD;ThreadDemo(String name, PrintDemo pd) {
threadName = name;
PD = pd;
}public void run() {
PD.printCount();
System.out.println("Thread " + threadName + " exiting.");
} public void start() {
System.out.println("Starting " + threadName);
if (t == null) {
t = new Thread(this, threadName);
t.start();} }
}public class TestThread {
public static void main(String args[]) {
PrintDemo PD = new PrintDemo();
ThreadDemo T1 = new ThreadDemo("Thread-1", PD);
ThreadDemo T2 = new ThreadDemo("Thread-2", PD);
T1.start();
T2.start();
try {
T1.join();
T2.join();
} catch (Exception e) {
System.out.println("Interrupted");}}}
output:
Starting Thread-1
Starting Thread-2
Counter - 5
Counter - 4
Counter - 3
Counter - 2
Counter - 1
Thread Thread-1 exiting.
Counter - 5
Counter - 4
Counter - 3
Counter - 2
Counter - 1
Thread Thread-2 exiting.
Multithreading Example with Synchronization:
Here is the same example which prints counter value in sequence and every time we run
it, it produces the same result.
classPrintDemo {
public void printCount() {
try {
for (inti = 5; i> 0; i--) {
System.out.println("Counter - " + i);}
} catch (Exception e) {
System.out.println("Thread interrupted.");}}}
classThreadDemo extends Thread {
private Thread t;
private String threadName;
PrintDemo PD;
ThreadDemo(String name, PrintDemopd) {
threadName = name;
PD = pd;
} public void run() {
synchronized (PD) {
PD.printCount();}
System.out.println("Thread " + threadName + " exiting.");
} public void start() {
System.out.println("Starting " + threadName);
if (t == null) {
t = new Thread(this, threadName);
t.start();}}}
public class TestThread {
public static void main(String args[]) {
PrintDemo PD = new PrintDemo();
ThreadDemo T1 = new ThreadDemo("Thread-1", PD);
ThreadDemo T2 = new ThreadDemo("Thread-2", PD);
T1.start();
T2.start();
try {
T1.join();
T2.join(); } catch (Exception e) {
System.out.println("Interrupted");}}}
output:
Starting Thread-1
Starting Thread-2
Counter - 5
Counter - 4
Counter - 3
Counter - 2
Counter - 1
Thread Thread-1 exiting.
Counter - 5
Counter - 4
Counter - 3
Counter - 2
Counter - 1
Thread Thread-2 exiting.
4.14 EXPLAIN INTER THREAD COMMUNICATION WITH EXAMPLE PROGRAM:
Java Interthread Communication:-
1.If you are aware of interprocess communication then it will be easy for you to
understand interthread communication.
3.There are three simple methods and a little trick which makes thread communication
possible. All the three methods are listed below.
These methods have been implemented as final methods in Object, so they are available
in all the classes. All three methods can be called only from within a synchronized
context.
Example: This example shows how two threads can communicate using wait() and
notify() method. You can create a complex system using the same concept.
Program code
class Chat {
boolean flag = false;
public synchronized void Question(String msg) {
if (flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();}}
System.out.println(msg);
flag = true;
notify();}
public synchronized void Answer(String msg) {
if (!flag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();}}
System.out.println(msg);
flag = false;
notify(); }}
class T1 implements Runnable {
Chat m;
String[] s1 = { "Hi", "How are you?", "I am also doing fine!" };
public T1(Chat m1) {
this.m = m1;
new Thread(this, "Question").start();
} public void run() {
for (inti = 0; i< s1.length; i++)
m.Question(s1[i]);}}
class T2 implements Runnable {
Chat m;
String[] s2 = { "Hi", "I am good, what about you?", "Great!" };
public T2(Chat m2) {
this.m = m2;
new Thread(this, "Answer").start();}
public void run() {
for (inti = 0; i< s2.length; i++)
m.Answer(s2[i]); }}
classTestThread {
public static void main(String[] args) {
Chat m = new Chat();
new T1(m);
new T2(m);}}
output:
Hi
Hi
How are you?
I am good, what about you?
I am also doing fine!
Great!
4.15 EXPLAIN DEAD LOCK:
Deadlock in Java:
2.Deadlock can occur in a situation when a thread is waiting for an object lock, that is
acquired by another thread and second thread is waiting for an object lock that is
acquired by first thread. Since, both threads are waiting for each other to release the lock,
the condition is called deadlock
Program code:
Avoid Nested Locks: We must avoid giving locks to multiple threads, this is the main
reason for a deadlock condition. It normally happens when you give locks to multiple
threads.
Avoid Unnecessary Locks: The locks should be given to the important threads. Giving
locks to the unnecessary threads that cause the deadlock condition.
Using Thread Join: A deadlock usually happens when one thread is waiting for the other
to finish. In this case, we can use join with a maximum time that a thread will take.