Java Exception Handling Explained
Java Exception Handling Explained
Exception Handling
The Exception Handling in Java is one of the powerful mechanism to handle the runtime
errors so that the normal flow of the application can be maintained.
In this tutorial, we will learn about Java exceptions, it's types, and the difference between
checked and unchecked exceptions.
In Java, an exception is an event that disrupts the normal flow of the program. It is an object
which is thrown at runtime.
The core advantage of exception handling is to maintain the normal flow of the
application. An exception normally disrupts the normal flow of the application; that
is why we need to handle exceptions. Let's consider a scenario:
1. statement 1;
2. statement 2;
3. statement 3;
4. statement 4;
5. statement 5;//exception occurs
6. statement 6;
7. statement 7;
8. statement 8;
9. statement 9;
10. statement 10;
1. Checked Exception
2. Unchecked Exception
3. Error
Difference between Checked and Unchecked
Exceptions
1) Checked Exception
The classes that directly inherit the Throwable class except RuntimeException and
Error are known as checked exceptions. For example, IOException, SQLException, etc.
Checked exceptions are checked at compile-time.
2) Unchecked Exception
The classes that inherit the RuntimeException are known as unchecked exceptions.
For example, ArithmeticException, NullPointerException,
ArrayIndexOutOfBoundsException, etc. Unchecked exceptions are not checked at
compile-time, but they are checked at runtime.
3) Error
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.
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.
[Link]
Output:
1. int a=50/0;//ArithmeticException
If we have a null value in any variable, performing any operation on the variable
throws a NullPointerException.
1. String s=null;
2. [Link]([Link]());//NullPointerException
1. String s="abc";
2. int i=[Link](s);//NumberFormatException
4) A scenario where ArrayIndexOutOfBoundsException occurs
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.
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:
But if the application programmer handles the exception, the normal flow of the
application is maintained, i.e., rest of the code is executed.
Example 1
[Link]
Output:
As displayed in the above example, the rest of the code is not executed (in 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 not handled,
all the code below the exception won't be executed.
Output:
[Link]: / by zero
rest of the code
As displayed in the above example, the rest of the code is executed, i.e., the rest of
the code statement is printed.
Example 3
In this example, we also kept the code in a try block that will not throw an exception.
[Link]
Output:
[Link]: / by zero
Here, we can see that if an exception occurs in the try block, the rest of the block
code will not execute.
Example 4
Here, we handle the exception using the parent class exception.
[Link]
Output:
[Link]: / by zero
rest of the code
Example 5
Let's see an example to print a custom message on exception.
[Link]
Output:
Example 6
Let's see an example to resolve the exception in a catch block.
[Link]
Output:
25
Example 7
In this example, along with try block, we also enclose exception code in a catch block.
[Link]
Output:
Here, we can see that the catch block didn't contain the exception code. So, enclose
exception code within a try block and use catch block only to handle the exceptions.
Example 8
In this example, we handle the generated exception (Arithmetic Exception) with a
different type of exception class (ArrayIndexOutOfBoundsException).
[Link]
Output:
Example 9
Let's see an example to handle another unchecked exception.
[Link]
Output:
[Link]: 10
rest of the code
Example 10
Let's see an example to handle checked exception.
[Link]
1. import [Link];
2. import [Link];
3.
4. public class TryCatchExample10 {
5.
6. public static void main(String[] args) {
7.
8.
9. PrintWriter pw;
10. try {
11. pw = new PrintWriter("[Link]"); //may throw exception
12. [Link]("saved");
13. }
14. // providing the checked exception handler
15. catch (FileNotFoundException e) {
16.
17. [Link](e);
18. }
19. [Link]("File saved successfully");
20. }
21. }
Output:
Points to remember
o At a time only one exception occurs and at a time only one catch block is executed.
o All catch blocks must be ordered from most specific to most general, i.e. catch for
ArithmeticException must come before catch for Exception.
Example 1
Let's see a simple example of java multi-catch block.
[Link]
Output:
Example 2
[Link]
Output:
In this example, try block contains two exceptions. But at a time only one exception
occurs and its corresponding catch block is executed.
[Link]
Output:
Example 4
In this example, we generate NullPointerException, but didn't provide the
corresponding exception type. In such case, the catch block containing the parent
exception class Exception will invoked.
[Link]
Output:
Example 5
Let's see an example, to handle the exception without maintaining the order of
exceptions (i.e. from most specific to most general).
[Link]
1. class MultipleCatchBlock5{
2. public static void main(String args[]){
3. try{
4. int a[]=new int[5];
5. a[5]=30/0;
6. }
7. catch(Exception e){[Link]("common task completed");}
8. catch(ArithmeticException e){[Link]("task1 is completed");}
9. catch(ArrayIndexOutOfBoundsException e){[Link]("task 2 completed");}
10. [Link]("rest of the code...");
11. }
12. }
Output:
Compile-time error
Java Nested try block
In Java, using a try block inside another try block is permitted. It is called as nested
try block. Every statement that we enter a statement in try block, context of that
exception is pushed onto the stack.
Syntax:
1. ....
2. //main try block
3. try
4. {
5. statement 1;
6. statement 2;
7. //try catch block within another try block
8. try
9. {
10. statement 3;
11. statement 4;
12. //try catch block within nested try block
13. try
14. {
15. statement 5;
16. statement 6;
17. }
18. catch(Exception e2)
19. {
20. //exception message
21. }
22.
23. }
24. catch(Exception e1)
25. {
26. //exception message
27. }
28. }
29. //catch block of parent (outer) try block
30. catch(Exception e3)
31. {
32. //exception message
33. }
34. ....
[Link]
Output:
When any try block does not have a catch block for a particular exception, then the
catch block of the outer (parent) try block are checked for that exception, and if it
matches, the catch block of outer try block is executed.
If none of the catch block specified in the code is unable to handle the exception,
then the Java runtime system will handle the exception. Then it displays the system
generated message for that exception.
Example 2
Let's consider the following example. Here the try block within nested try block (inner
try block 2) do not handle the exception. The control is then transferred to its parent
try block (inner try block 1). If it does not handle the exception, then the control is
transferred to the main try block (outer try block) where the appropriate catch block
handles the exception. It is termed as nesting.
[Link]
Output:
Java finally block
Java finally block is a block used to execute important code such as closing the
connection, etc.
Note: If you don't handle the exception, before terminating the program, JVM executes
finally block (if any).
[Link]
1. class TestFinallyBlock {
2. public static void main(String args[]){
3. try{
4. //below code do not throw any exception
5. int data=25/5;
6. [Link](data);
7. }
8. //catch won't be executed
9. catch(NullPointerException e){
10. [Link](e);
11. }
12. //executed regardless of exception occurred or not
13. finally {
14. [Link]("finally block is always executed");
15. }
16.
17. [Link]("rest of phe code...");
18. }
19. }
Output:
Case 2: When an exception occurr but not handled by the catch
block
Let's see the the fillowing 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.
[Link]
Output:
Case 3: When an exception occurs and is handled by the catch
block
Example:
Let's see the following example where the Java code throws an exception and the
catch block handles the exception. Later the finally block is executed after the try-
catch block. Further, the rest of the code is also executed normally.
[Link]
Output:
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 exits (either by calling
[Link]() 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 also define our own set of conditions and throw an exception explicitly using
throw keyword. For example, we can throw ArithmeticException if we divide a
number by another number. Here, we just need to set the condition and throw
exception using throw keyword.
The syntax of the Java throw keyword is given below.
[Link]
In this example, we have created the validate method that takes integer value as a
parameter. If the age is less than 18, we are throwing the ArithmeticException
otherwise print a message welcome to vote.
Output:
The above code throw an unchecked exception. Similarly, we can also throw
unchecked and user defined exceptions.
Note: If we throw unchecked exception from a method, it is must to handle the exception
or declare in throws clause.
[Link]
1. import [Link].*;
2.
3. public class TestThrow2 {
4.
5. //function to check if person is eligible to vote or not
6. public static void method() throws FileNotFoundException {
7.
8. FileReader file = new FileReader("C:\\Users\\Anurati\\Desktop\\[Link]");
9. BufferedReader fileInput = new BufferedReader(file);
10.
11.
12. throw new FileNotFoundException();
13.
14. }
15. //main method
16. public static void main(String args[]){
17. try
18. {
19. method();
20. }
21. catch (FileNotFoundException e)
22. {
23. [Link]();
24. }
25. [Link]("rest of the code...");
26. }
27. }
Output:
[Link]
Output:
1. class TestExceptionPropagation1{
2. void m(){
3. int data=50/0;
4. }
5. void n(){
6. m();
7. }
8. void p(){
9. try{
10. n();
11. }catch(Exception e){[Link]("exception handled");}
12. }
13. public static void main(String args[]){
14. TestExceptionPropagation1 obj=new TestExceptionPropagation1();
15. obj.p();
16. [Link]("normal flow...");
17. }
18. }
Output:
exception handled
normal flow...
In the above example exception occurs in the m() method where it is not handled, so
it is propagated to the previous n() method where it is not handled, again it is
propagated to the p() method where exception is handled.
Exception can be handled in any method in call stack either in the main() method, p()
method, n() method or m() method.
Note: By default, Checked Exceptions are not forwarded in calling chain (propagated).
1. class TestExceptionPropagation2{
2. void m(){
3. throw new [Link]("device error");//checked exception
4. }
5. void n(){
6. m();
7. }
8. void p(){
9. try{
10. n();
11. }catch(Exception e){[Link]("exception handeled");}
12. }
13. public static void main(String args[]){
14. TestExceptionPropagation2 obj=new TestExceptionPropagation2();
15. obj.p();
16. [Link]("normal flow");
17. }
18. }
Output:
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.
[Link]
1. import [Link];
2. class Testthrows1{
3. void m()throws IOException{
4. throw new IOException("device error");//checked exception
5. }
6. void n()throws IOException{
7. m();
8. }
9. void p(){
10. try{
11. n();
12. }catch(Exception e){[Link]("exception handled");}
13. }
14. public static void main(String args[]){
15. Testthrows1 obj=new Testthrows1();
16. obj.p();
17. [Link]("normal flow...");
18. }
19. }
Output:
exception handled
normal flow...
Rule: If we are calling a method that declares an exception, we must either caught or
declare the exception.
1. Case 1: We have caught the exception i.e. we have handled the exception using
try/catch block.
2. Case 2: We have declared the exception i.e. specified throws keyword with the
method.
[Link]
1. import [Link].*;
2. class M{
3. void method()throws IOException{
4. throw new IOException("device error");
5. }
6. }
7. public class Testthrows2{
8. public static void main(String args[]){
9. try{
10. M m=new M();
11. [Link]();
12. }catch(Exception e){[Link]("exception handled");}
13.
14. [Link]("normal flow...");
15. }
16. }
Output:
exception handled
normal flow...
[Link]
1. import [Link].*;
2. class M{
3. void method()throws IOException{
4. [Link]("device operation performed");
5. }
6. }
7. class Testthrows3{
8. public static void main(String args[])throws IOException{//declare exception
9. M m=new M();
10. [Link]();
11.
12. [Link]("normal flow...");
13. }
14. }
Output:
B) If exception occurs
[Link]
1. import [Link].*;
2. class M{
3. void method()throws IOException{
4. throw new IOException("device error");
5. }
6. }
7. class Testthrows4{
8. public static void main(String args[])throws IOException{//declare exception
9. M m=new M();
10. [Link]();
11.
12. [Link]("normal flow...");
13. }
14. }
Output:
Difference between throw and throws in Java
The throw and throws is the concept of exception handling where the throw keyword
throw the exception explicitly from a method or a block of code whereas the throws
keyword is used in signature of the method.
There are many differences between throw and throws keywords. A list of differences
between throw and throws are given below:
Output:
Output:
Output:
Along with this, there are many differences between final, finally and finalize. A list of
differences between final, finally and finalize are given below:
2. Applicable Final keyword is used Finally block is always finalize() method is used
to with the classes, related to the try and with the objects.
methods and catch block in exception
variables. handling.
3. Functionality (1) Once declared, (1) finally block runs the finalize method
final variable becomes important code even if performs the cleaning
constant and cannot exception occurs or not. activities with respect to
be modified. (2) finally block cleans the object before its
(2) final method up all the resources destruction.
cannot be overridden used in try block
by sub class.
(3) final class cannot
be inherited.
[Link]
Output:
In the above example, we have declared a variable final. Similarly, we can declare the
methods and classes final using the final keyword.
[Link]
Output:
Output:
1. import [Link].*;
2. class Parent{
3.
4. // defining the method
5. void msg() {
6. [Link]("parent method");
7. }
8. }
9.
10. public class TestExceptionChild extends Parent{
11.
12. // overriding the method in child class
13. // gives compile time error
14. void msg() throws IOException {
15. [Link]("TestExceptionChild");
16. }
17.
18. public static void main(String args[]) {
19. Parent p = new TestExceptionChild();
20. [Link]();
21. }
22. }
Output:
Rule 2: If the superclass method does not declare an exception, subclass overridden
method cannot declare the checked exception but can declare unchecked exception.
[Link]
1. import [Link].*;
2. class Parent{
3. void msg() {
4. [Link]("parent method");
5. }
6. }
7.
8. class TestExceptionChild1 extends Parent{
9. void msg()throws ArithmeticException {
10. [Link]("child method");
11. }
12.
13. public static void main(String args[]) {
14. Parent p = new TestExceptionChild1();
15. [Link]();
16. }
17. }
Output:
1. import [Link].*;
2. class Parent{
3. void msg()throws ArithmeticException {
4. [Link]("parent method");
5. }
6. }
7.
8. public class TestExceptionChild2 extends Parent{
9. void msg()throws Exception {
10. [Link]("child method");
11. }
12.
13. public static void main(String args[]) {
14. Parent p = new TestExceptionChild2();
15.
16. try {
17. [Link]();
18. }
19. catch (Exception e){}
20.
21. }
22. }
Output:
1. import [Link].*;
2. class Parent{
3. void msg() throws Exception {
4. [Link]("parent method");
5. }
6. }
7.
8. public class TestExceptionChild3 extends Parent {
9. void msg()throws Exception {
10. [Link]("child method");
11. }
12.
13. public static void main(String args[]){
14. Parent p = new TestExceptionChild3();
15.
16. try {
17. [Link]();
18. }
19. catch(Exception e) {}
20. }
21. }
Output:
1. import [Link].*;
2. class Parent{
3. void msg()throws Exception {
4. [Link]("parent method");
5. }
6. }
7.
8. class TestExceptionChild4 extends Parent{
9. void msg()throws ArithmeticException {
10. [Link]("child method");
11. }
12.
13. public static void main(String args[]){
14. Parent p = new TestExceptionChild4();
15.
16. try {
17. [Link]();
18. }
19. catch(Exception e) {}
20. }
21. }
Output:
ADVERTISEMENT
1. import [Link].*;
2. class Parent {
3. void msg()throws Exception{
4. [Link]("parent method");
5. }
6. }
7.
8. class TestExceptionChild5 extends Parent{
9. void msg() {
10. [Link]("child method");
11. }
12.
13. public static void main(String args[]){
14. Parent p = new TestExceptionChild5();
15.
16. try {
17. [Link]();
18. }
19. catch(Exception e) {}
20.
21. }
22. }
Output:
Multithreading in Java
try {
[Link](
+ " is running");
catch (Exception e) {
// Throwing an exception
[Link]("Exception is caught");
// Main Class
MultithreadingDemo object
= new MultithreadingDemo();
[Link]();
Output
Thread 15 is running
Thread 14 is running
Thread 16 is running
Thread 12 is running
Thread 11 is running
Thread 13 is running
Thread 18 is running
Thread 17 is running
Thread creation by implementing the Runnable Interface
We create a new class which implements [Link] interface and
override run() method. Then we instantiate a Thread object and call start()
method on this object.
try {
[Link](
"Thread " + [Link]().getId()
+ " is running");
catch (Exception e) {
// Throwing an exception
[Link]("Exception is caught");
// Main Class
class Multithread {
Thread object
[Link]();
}
Output
Thread 13 is running
Thread 11 is running
Thread 12 is running
Thread 15 is running
Thread 14 is running
Thread 18 is running
Thread 17 is running
Thread 16 is running
Thread Class vs Runnable Interface
1. If we extend the Thread class, our class cannot extend any other class
because Java doesn’t support multiple inheritance. But, if we implement
the Runnable interface, our class can still extend other base classes.
2. We can achieve basic functionality of a thread by extending Thread class
because it provides some inbuilt methods like yield(), interrupt() etc. that
are not available in Runnable interface.
3. Using runnable will give you an object that can be shared amongst
multiple threads.
Java’s multithreading provides benefit in this area by eliminating the loop and
polling mechanism, one thread can be paused without stopping the other parts of
the program. If any thread is paused or blocked, still other threads continue to run.
As the process has several states, similarly a thread exists in several states. A
thread can be in the following states:
Ready to run (New): First time as soon as it gets CPU time.
Running: Under execution.
Suspended: Temporarily not active or under execution.
Blocked: Waiting for resources.
Resumed: Suspended thread resumed, and start from where it left off.
Terminated: Halts the execution immediately and never resumes.
Each thread has its own priority in Java. Thread priority is an absolute integer value.
Thread priority decides only when a thread switches from one running thread to
next, called context switching. Priority does increase the running time of the thread
or gives faster execution.
Synchronization
A program is a collection of more than one thread. Threads can communicate with
each other. Java supports messaging between the threads with lost-cost. It provides
methods to all objects for inter-thread communication. As a thread exits from
synchronization state, it notifies all the waiting threads.
1. New
2. Active
3. Blocked / Waiting
4. Timed Waiting
5. Terminated
Active: When a thread invokes the start() method, it moves from the new state to the
active state. The active state contains two states within it: one is runnable, and the
other is running.
o Runnable: A thread, that is ready to run is then moved to the runnable state. In the
runnable state, the thread may be running or may be ready to run at any given
instant of time. It is the duty of the thread scheduler to provide the thread time to
run, i.e., moving the thread the running state.
A program implementing multithreading acquires a fixed slice of time to each
individual thread. Each and every thread runs for a short span of time and when that
allocated time slice is over, the thread voluntarily gives up the CPU to the other
thread, so that the other threads can also run for their slice of time. Whenever such a
scenario occurs, all those threads that are willing to run, waiting for their turn to run,
lie in the runnable state. In the runnable state, there is a queue where the threads lie.
o Running: When the thread gets the CPU, it moves from the runnable to the running
state. Generally, the most common change in the state of a thread is from runnable
to running and again back to runnable.
Blocked or Waiting: Whenever a thread is inactive for a span of time (not
permanently) then, either the thread is in the blocked state or is in the waiting state.
For example, a thread (let's say its name is A) may want to print some data from the
printer. However, at the same time, the other thread (let's say its name is B) is using
the printer to print some data. Therefore, thread A has to wait for thread B to use the
printer. Thus, thread A is in the blocked state. A thread in the blocked state is unable
to perform any execution and thus never consume any cycle of the Central
Processing Unit (CPU). Hence, we can say that thread A remains idle until the thread
scheduler reactivates thread A, which is in the waiting or blocked state.
When the main thread invokes the join() method then, it is said that the main thread
is in the waiting state. The main thread then waits for the child threads to complete
their tasks. When the child threads complete their job, a notification is sent to the
main thread, which again moves the thread from waiting to the active state.
If there are a lot of threads in the waiting or blocked state, then it is the duty of the
thread scheduler to determine which thread to choose and which one to reject, and
the chosen thread is then given the opportunity to run.
Timed Waiting: Sometimes, waiting for leads to starvation. For example, a thread (its
name is A) has entered the critical section of a code and is not willing to leave that
critical section. In such a scenario, another thread (its name is B) has to wait forever,
which leads to starvation. To avoid such scenario, a timed waiting state is given to
thread B. Thus, thread lies in the waiting state for a specific span of time, and not
forever. A real example of timed waiting is when we invoke the sleep() method on a
specific thread. The sleep() method puts the thread in the timed wait state. After the
time runs out, the thread wakes up and start its execution from when it has left
earlier.
o When a thread has finished its job, then it exists or terminates normally.
o Abnormal termination: It occurs when some unusual events such as an unhandled
exception or segmentation fault.
A terminated thread means the thread is no more in the system. In other words, the
thread is dead, and there is no way one can respawn (active after kill) the dead
thread.
The following diagram shows the different states involved in the life cycle of a thread.
Implementation of Thread States
In Java, one can get the current state of a thread using
the [Link]() method. The [Link] class of Java provides
the constants ENUM to represent the state of a thread. These constants are:
It represents the runnable [Link] means a thread is waiting in the queue to run.
It represents the blocked state. In this state, the thread is waiting to acquire a lock.
It represents the waiting state. A thread will go to this state when it invokes the
[Link]() method, or [Link]() method with no timeout. A thread in the
waiting state is waiting for another thread to complete its task.
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. A thread invoking the following method reaches the timed
waiting state.
o sleep
o join with timeout
o wait with timeout
o parkUntil
o parkNanos
FileName: [Link]
Output:
Explanation: Whenever we spawn a new thread, that thread attains the new state.
When the method start() is invoked on a thread, the thread scheduler moves that
thread to the runnable state. Whenever the join() method is invoked on any thread
instance, the current thread executing that statement has to wait for this thread to
finish its execution, i.e., move that thread to the terminated state. Therefore, before
the final print statement is printed on the console, the program invokes the method
join() on thread t2, making the thread t1 wait while the thread t2 finishes its
execution and thus, the thread t2 get to the terminated or dead state. Thread t1 goes
to the waiting state because it is waiting for thread t2 to finish it's execution as it has
invoked the method join() on thread t2.
Thread class:
Thread class provide constructors and methods to create and perform operations on
a [Link] class extends Object class and implements Runnable interface.
Starting a thread:
The start() method of Thread class is used to start a newly created thread. It
performs the following tasks:
Output:
thread is running...
Output:
thread is running...
If you are not extending the Thread class, your class object would not be treated as a
thread object. So you need to explicitly create the Thread class object. We are
passing the object of your class that implements Runnable so that your class run()
method may execute.
FileName: [Link]
My first thread
FileName: [Link]
Output:
My new thread
Now the thread is running ...
Thread Scheduler in Java
A component of Java that decides which thread to run or execute and which thread
to wait is called a thread scheduler in Java. In Java, a thread is only chosen by a
thread scheduler if it is in the runnable state. However, if there is more than one
thread in the runnable state, it is up to the thread scheduler to pick one of the
threads and ignore the other ones. There are some criteria that decide which thread
will execute first. There are two factors for scheduling a thread i.e. Priority and Time
of arrival.
Priority: Priority of each thread lies between 1 to 10. If a thread has a higher priority,
it means that thread has got a better chance of getting picked up by the thread
scheduler.
Time of Arrival: Suppose two threads of the same priority enter the runnable state,
then priority cannot be the factor to pick a thread from these two threads. In such a
case, arrival time of thread is considered by the thread scheduler. A thread that
arrived first gets the preference over the other threads.
t1 0
t2 1
t3 2
t4 3
In the above table, we can see that Thread t1 has arrived first, then Thread t2, then
t3, and at last t4, and the order in which the threads will be processed is according to
the time of arrival of threads.
Hence, Thread t1 will be processed first, and Thread t4 will be processed last.
Time-slicing scheduling:
Usually, the First Come First Serve algorithm is non-preemptive, which is bad as it
may lead to infinite blocking (also known as starvation). To avoid that, some time-
slices are provided to the threads so that after some time, the running thread has to
give up the CPU. Thus, the other waiting threads also get time to run their job.
In the above diagram, each thread is given a time slice of 2 seconds. Thus, after 2
seconds, the first thread leaves the CPU, and the CPU is then captured by Thread2.
The same process repeats for the other threads too.
Preemptive-Priority Scheduling:
The name of the scheduling algorithm denotes that the algorithm is related to the
priority of the threads.
Suppose there are multiple threads available in the runnable state. The thread
scheduler picks that thread that has the highest priority. Since the algorithm is also
preemptive, therefore, time slices are also provided to the threads to avoid
starvation. Thus, after some time, even if the highest priority thread has not
completed its job, it has to release the CPU because of preemption.
The thread scheduler selects the thread that has the highest priority, and the thread
begins the execution of the job. If a thread is already in runnable state and another
thread (that has higher priority) reaches in the runnable state, then the current thread
is pre-empted from the processor, and the arrived thread with higher priority gets
the CPU time.
When two threads (Thread 2 and Thread 3) having the same priorities and arrival
time, the scheduling will be decided on the basis of FCFS algorithm. Thus, the thread
that arrives first gets the opportunity to execute first.
The method sleep() with the one parameter is the native method, and the
implementation of the native method is accomplished in another programming
language. The other methods having the two parameters are not the native method.
That is, its implementation is accomplished in Java. We can access the sleep()
methods with the help of the Thread class, as the signature of the sleep() methods
contain the static keyword. The native, as well as the non-native method, throw a
checked Exception. Therefore, either try-catch block or the throws keyword can work
here.
The [Link]() method can be used with any thread. It means any other thread or
the main thread can invoke the sleep() method.
Parameters:
The following are the parameters used in the sleep() method.
mls: The time in milliseconds is represented by the parameter mls. The duration for
which the thread will sleep is given by the method sleep().
n: It shows the additional time up to which the programmer or developer wants the
thread to be in the sleeping state. The range of n is from 0 to 999999.
Whenever another thread does interruption while the current thread is already in the
sleep mode, then the InterruptedException is thrown.
If the system that is executing the threads is busy, then the actual sleeping time of
the thread is generally more as compared to the time passed in arguments. However,
if the system executing the sleep() method has less load, then the actual sleeping
time of the thread is almost equal to the time passed in the argument.
Example of the sleep() method in Java : on the custom thread
The following example shows how one can use the sleep() method on the custom
thread.
FileName: [Link]
Output:
1
1
2
2
3
3
4
4
As you know well that at a time only one thread is executed. If you sleep a thread for
the specified time, the thread scheduler picks up another thread and so on.
Output:
0
1
2
3
4
Example of the sleep() Method in Java: When the sleeping time
is -ive
The following example throws the exception IllegalArguementException when the
time for sleeping is negative.
FileName: [Link]
Output:
Output:
running
Exception in thread "main" [Link]
+ [Link]().getName());
[Link]();
{
[Link]([Link]().getName()
Output:
Main thread is- main
Thread-0, executing run() method!
The output shows two active threads in the program – main thread and
Thread-0, main method is executed by the Main thread but invoking the start
on RunnableImpl creates and starts a new thread – Thread-0. What
happens when Runnable encounters an exception ? Runnable can’t
throw checked exception but RuntimeException can be thrown from the
run(). Uncaught exceptions are handled by the exception handler of the
thread, if JVM can’t handle or catch exceptions, it prints the stack trace and
terminates the flow.
o wait()
o notify()
o notifyAll()
1) wait() method
The wait() method causes current thread to release the lock and wait until either
another thread invokes the notify() method or the notifyAll() method for this object,
or a specified amount of time has elapsed.
The current thread must own this object's monitor, so it must be called from the
synchronized method only otherwise it will throw exception.
Method Description
public final void wait(long timeout)throws It waits for the specified amount of
InterruptedException time.
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:
3) notifyAll() method
Wakes up all threads that are waiting on this object's monitor.
Syntax:
wait() sleep()
The wait() method releases the lock. The sleep() method doesn't release the lock.
It is a method of Object class It is a method of Thread class
It should be notified by notify() or notifyAll() After the specified amount of time, sleep is
methods completed.
[Link]
1. class Customer{
2. int amount=10000;
3.
4. synchronized void withdraw(int amount){
5. [Link]("going to withdraw...");
6.
7. if([Link]<amount){
8. [Link]("Less balance; waiting for deposit...");
9. try{wait();}catch(Exception e){}
10. }
11. [Link]-=amount;
12. [Link]("withdraw completed...");
13. }
14.
15. synchronized void deposit(int amount){
16. [Link]("going to deposit...");
17. [Link]+=amount;
18. [Link]("deposit completed... ");
19. notify();
20. }
21. }
22.
23. class Test{
24. public static void main(String args[]){
25. final Customer c=new Customer();
26. new Thread(){
27. public void run(){[Link](15000);}
28. }.start();
29. new Thread(){
30. public void run(){[Link](10000);}
31. }.start();
32.
33. }}
Output:
going to withdraw...
Less balance; waiting for deposit...
going to deposit...
deposit completed...
withdraw completed
The suspend() method of thread class puts the thread from running to waiting state.
This method is used if you want to stop the thread execution and start it again when
a certain event occurs. This method allows a thread to temporarily cease execution.
The suspended thread can be resumed using the resume() method.
Syntax
1. public final void suspend()
Return
This method does not return any value.
Exception
SecurityException: If the current thread cannot modify the thread.
Example
1. public class JavaSuspendExp extends Thread
2. {
3. public void run()
4. {
5. for(int i=1; i<5; i++)
6. {
7. try
8. {
9. // thread to sleep for 500 milliseconds
10. sleep(500);
11. [Link]([Link]().getName());
12. }catch(InterruptedException e){[Link](e);}
13. [Link](i);
14. }
15. }
16. public static void main(String args[])
17. {
18. // creating three threads
19. JavaSuspendExp t1=new JavaSuspendExp ();
20. JavaSuspendExp t2=new JavaSuspendExp ();
21. JavaSuspendExp t3=new JavaSuspendExp ();
22. // call run() method
23. [Link]();
24. [Link]();
25. // suspend t2 thread
26. [Link]();
27. // call run() method
28. [Link]();
29. }
30. }
Output:
Thread-0
1
Thread-2
1
Thread-0
2
Thread-2
2
Thread-0
3
Thread-2
3
Thread-0
4
Thread-2
4
Syntax
1. public final void resume()
Return value
This method does not return any value.
Exception
SecurityException: If the current thread cannot modify the thread.
Example
1. public class JavaResumeExp extends Thread
2. {
3. public void run()
4. {
5. for(int i=1; i<5; i++)
6. {
7. try
8. {
9. // thread to sleep for 500 milliseconds
10. sleep(500);
11. [Link]([Link]().getName());
12. }catch(InterruptedException e){[Link](e);}
13. [Link](i);
14. }
15. }
16. public static void main(String args[])
17. {
18. // creating three threads
19. JavaResumeExp t1=new JavaResumeExp ();
20. JavaResumeExp t2=new JavaResumeExp ();
21. JavaResumeExp t3=new JavaResumeExp ();
22. // call run() method
23. [Link]();
24. [Link]();
25. [Link](); // suspend t2 thread
26. // call run() method
27. [Link]();
28. [Link](); // resume t2 thread
29. }
30. }
Output:
Thread-0
1
Thread-2
1
Thread-1
1
Thread-0
2
Thread-2
2
Thread-1
2
Thread-0
3
Thread-2
3
Thread-1
3
Thread-0
4
Thread-2
4
Thread-1
4
The stop() method of thread class terminates the thread execution. Once a thread is
stopped, it cannot be restarted by start() method.
Syntax
1. public final void stop()
2. public final void stop(Throwable obj)
Parameter
obj : The Throwable object to be thrown.
Return
This method does not return any value.
Exception
SecurityException: This exception throws if the current thread cannot modify the
thread.
Example
1. public class JavaStopExp extends Thread
2. {
3. public void run()
4. {
5. for(int i=1; i<5; i++)
6. {
7. try
8. {
9. // thread to sleep for 500 milliseconds
10. sleep(500);
11. [Link]([Link]().getName());
12. }catch(InterruptedException e){[Link](e);}
13. [Link](i);
14. }
15. }
16. public static void main(String args[])
17. {
18. // creating three threads
19. JavaStopExp t1=new JavaStopExp ();
20. JavaStopExp t2=new JavaStopExp ();
21. JavaStopExp t3=new JavaStopExp ();
22. // call run() method
23. [Link]();
24. [Link]();
25. // stop t3 thread
26. [Link]();
27. [Link]("Thread t3 is stopped");
28. }
29. }