Exception Handling and Multithreading in Java
Exception handling and multithreading are two essential concepts in the Java programming language that are used to improve the performance and reliability of a program. Exception handling is a mechanism that allows a program to handle errors and exceptional events, while multithreading is a technique that enables a program to perform multiple tasks simultaneously. In this article, we will discuss the basics of exception handling and multithreading in Java and how they can be used to improve the performance and reliability of your programs.
Try-catch-finally blocks are used in Java to handle exceptions. The catch block provides intended to catch exceptions, and the try block is utilized to contain code that might throw them. Any resources spent in the try block are cleaned up in the finally block. For example, the following code snippet shows how to handle a FileNotFoundException, which is thrown when a file that is to be read cannot be found:
try {
FileInputStream file = new FileInputStream("file.txt");
int data = file.read();
// do something with data
} catch (FileNotFoundException e) {
System.err.println("File not found: " + e.getMessage());
} finally {
file.close();
}
In this example, the try block is used to open the file and read its contents, while the catch block is used to handle the FileNotFoundException that may be thrown. No matter whether this exception was thrown, closing the file is done in the finally block.
Another important feature of exception handling in Java is the ability to throw custom exceptions. It allows you to create your own exception classes that can be thrown and caught in your code. For example, you might create a custom exception class called InvalidDataException, which is thrown when the data read from a file is invalid:
class InvalidDataException extends Exception {
public InvalidDataException(String message) {
super(message);
}
}
In this example, the InvalidDataException class is a subclass of the Exception class, and it takes a message as its constructor argument. Just like any other Java exception, such customized exception can indeed be thrown and handled in the same manner.
When a class inherits the thread class as well as overrides the run() method, a new thread is created in this instance. This activates the new thread's entry point that was generated in the class that extended the thread class. Additionally, the program's thread is launched and operated using the start() method.
File name: Aman.java
// Java programme that uses threads and exceptions
// Importing Files and Classes
import java.io.*;
// The parent Class, which the child Class (Thread) inherits (Aman)
class Aman extends Thread {
// The ability to determine whether a thread is active
public void run()
{
System.out.println("It is a running thread");
// iterating with a for loop
for (int s = 0; s < 10; ++s) {
System.out.println("running the thread loop" + s);
}
}
// Loading the Main Driver Method
public static void main(String[] args)
{
// attempt-catch block for exception detection
try {
// Creation of the new thread
Aman srj = new Aman();
throw new RuntimeException();
}
// To manage exceptions, use a catch block.
catch (Exception e) {
System.out.println(
" There is no support for another thread. ");
}
}
}
Output:
There is no support for another thread
Now that we have covered exception handling, let's turn our attention to multithreading. Multithreading is a technique that allows a program to perform multiple tasks simultaneously, by creating and managing multiple threads of execution. Creating and managing threads in Java is done and used the Thread class as well as the Runnable interface. The Executable interface specifies a single function, run(), that includes the code that is going to be performed by the thread, whereas the Thread class offers techniques for initiating, stopping, and regulating the execution of such a thread.
For example, the following code snippet shows how to create and start a new thread:
class MyThread extends Thread {
public void run() {
// code to be executed by the thread
}
}
MyThread myThread = new MyThread();
myThread.start();
As shown, the run() method is overridden by the MyThread class, which extends the Thread class, to specify the thread's intended course of action. The start() method is then invoked in order to start the thread's execution, after which an instance of such MyThread class is created.