Unit - 5
Multithreading in Java
Q1) Write short notes on multithreading?
A1) Multithreading
In Java, multithreading is the process of running several threads at the same time.
A thread is the smallest unit of processing and is a lightweight sub-process. Multitasking is accomplished through the use of multiprocessing and multithreading.
Because threads share memory, we employ multithreading rather than multiprocessing. They conserve memory by not allocating a separate memory space, and context-switching between threads takes less time than processing.
Multithreading in Java is typically utilized in gaming, animation, and other similar applications.
Because Java is a multi-threaded programming language, we can use it to create multi-threaded programs. A multi-threaded program is made up of two or more portions that can operate in parallel, each of which can tackle a distinct task at the same time, maximizing the use of available resources, especially when your computer has several CPUs.
Multitasking is defined as the sharing of common processing resources, such as a CPU, by many processes. Multi-threading extends the concept of multitasking into programs by allowing you to divide certain operations within a single app into several threads. Each thread can execute in its own thread. Not only does the operating system split processing time among distinct apps, but it also divides it among each thread within an application.
Multi-threading allows you to write software in which multiple activities can run at the same time.
Q2) Explain the Java Thread Model?
A2) Threads exist in several states. A thread can be running. It can be ready to run as soon as it gets CPU time. A running thread can be suspended, which temporarily halts its activity. A suspended thread can then be resumed, allowing it to pick up where it left off. A thread can be blocked when waiting for a resource. At any time, a thread can be terminated, which halts its execution immediately. Once terminated, a thread cannot be resumed.
Life Cycle of a Thread
A thread goes through various stages in its life cycle. For example, a thread is born, started, runs, and then dies. The following diagram shows the complete life cycle of a thread.
Fig - The complete life cycle of a thread
Following are the stages of the life cycle −
● 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.
● Runnable − After a newly born thread is started, the thread becomes runnable. A thread in this state is considered to be executing its task.
● Waiting − Sometimes, a thread transitions to the waiting state while the thread waits for another thread to perform a task. A thread transitions back to the runnable state only when another thread signals the waiting thread to continue executing.
● Timed Waiting − A runnable thread can enter the timed waiting state for a specified interval of time. A thread in this state transitions back to the runnable state when that time interval expires or when the event it is waiting for occurs.
● Terminated (Dead) − A runnable thread enters the terminated state when it completes its task or otherwise terminates.
Q3) Explain Thread Priorities in java?
A3) Java assigns to each thread a priority that determines how that thread should be treated with respect to the others. Thread priorities are integers that specify the relative priority of one thread to another. As an absolute value, a priority is meaningless; a higher-priority thread doesn’t run any faster than a lower-priority thread if it is the only thread running.
Instead, a thread’s priority is used to decide when to switch from one running thread to the next. This is called a context switch. The rules that determine when a context switch takes place are simple:
A thread can voluntarily relinquish control. This is done by explicitly yielding, sleeping, or blocking on pending I/O. In this scenario, all other threads are examined, and the highest-priority thread that is ready to run is given the CPU.
A thread can be preempted by a higher-priority thread. In this case, a lower-priority thread that does not yield the processor is simply preempted—no matter what it is doing— by a higher-priority thread. Basically, as soon as a higher-priority thread wants to run, it does. This is called preemptive multitasking.
In cases where two threads with the same priority are competing for CPU cycles, the situation is a bit complicated. For operating systems such as Windows, threads of equal priority are time-sliced automatically in round-robin fashion. For other types of operating systems, threads of equal priority must voluntarily yield control to their peers. If they don’t, the other threads will not run.
Q4) What is synchronization and messaging in java?
A4) Synchronization
Because multithreading introduces an asynchronous behavior to your programs, there must be a way for you to enforce synchronicity when you need it. For example, if you want two threads to communicate and share a complicated data structure, such as a linked list, you need some way to ensure that they don’t conflict with each other. That is, you must prevent one thread from writing data while another thread is in the middle of reading it.
For this purpose, Java implements an elegant twist on an age-old model of interprocess synchronization: the monitor. The monitor is a control mechanism first defined by C.A.R. Hoare. You can think of a monitor as a very small box that can hold only one thread. Once a thread enters a monitor, all other threads must wait until that thread exits the monitor. In this way, a monitor can be used to protect a shared asset from being manipulated by more than one thread at a time.
In Java, there is no class “Monitor”; instead, each object has its own implicit monitor that is automatically entered when one of the object’s synchronized methods is called. Once a thread is inside a synchronized method, no other thread can call any other synchronized method on the same object. This enables you to write very clear and concise multithreaded code, because synchronization support is built into the language.
Messaging
After you divide your program into separate threads, you need to define how they will communicate with each other. When programming with some other languages, you must depend on the operating system to establish communication between threads. This, of course, adds overhead. By contrast, Java provides a clean, low-cost way for two or more threads to talk to each other, via calls to predefined methods that all objects have. Java’s messaging system allows a thread to enter a synchronized method on an object, and then wait there until some other thread explicitly notifies it to come out.
Q5) What are thread methods?
A5) Following is the list of important methods available in the Thread class.
Sr.No. | Method & Description |
1 | Public void start() Starts the thread in a separate path of execution, then invokes the run() method on this Thread object. |
2 | Public void run() If this Thread object was instantiated using a separate Runnable target, the run() method is invoked on that Runnable object. |
3 | Public final void setName(String name) Changes the name of the Thread object. There is also a getName() method for retrieving the name. |
4 | Public final void setPriority(int priority) Sets the priority of this Thread object. The possible values are between 1 and 10. |
5 | Public final void setDaemon(boolean on) A parameter of true denotes this Thread as a daemon thread. |
6 | Public final void join(long millisec) The current thread invokes this method on a second thread, causing the current thread to block until the second thread terminates or the specified number of milliseconds passes. |
7 | Public void interrupt() Interrupts this thread, causing it to continue execution if it was blocked for any reason. |
8 | Public final boolean isAlive() Returns true if the thread is alive, which is any time after the thread has been started but before it runs to completion. |
The previous methods are invoked on a particular Thread object. The following methods in the Thread class are static. Invoking one of the static methods performs the operation on the currently running thread.
Sr.No. | Method & Description |
1 | Public static void yield() Causes the currently running thread to yield to any other threads of the same priority that are waiting to be scheduled. |
2 | Public static void sleep(long millisec) Causes the currently running thread to block for at least the specified number of milliseconds. |
3 | Public static boolean holdsLock(Object x) Returns true if the current thread holds the lock on the given Object. |
4 | Public static Thread currentThread() Returns a reference to the currently running thread, which is the thread that invokes this method. |
5 | Public static void dumpStack() Prints the stack trace for the currently running thread, which is useful when debugging a multithreaded application. |
Q6) Write any example of thread?
A6) The following Thread Class Demo program demonstrates some of these methods of the Thread class. Consider a class Display Message which implements Runnable −
// File Name : DisplayMessage.java
// Create a thread to implement Runnable
Public class DisplayMessage implements Runnable {
Private String message;
Public DisplayMessage(String message) {
This.message = message;
}
Public void run() {
While(true) {
System.out.println(message);
}
}
}
Following is another class which extends the Thread class −
// File Name : GuessANumber.java
// Create a thread to extend Thread
Public class GuessANumber extends Thread {
Private int number;
Public GuessANumber(int number) {
This.number = number;
}
Public void run() {
Int counter = 0;
Int guess = 0;
Do {
Guess = (int) (Math.random() * 100 + 1);
System.out.println(this.getName() + " guesses " + guess);
Counter++;
} while(guess != number);
System.out.println("** Correct!" + this.getName() + "in" + counter + "guesses.**");
}
}
Following is the main program, which makes use of the above-defined classes −
// File Name : ThreadClassDemo.java
Public class ThreadClassDemo {
Public static void main(String [] args) {
Runnable hello = new DisplayMessage("Hello");
Thread thread1 = new Thread(hello);
Thread1.setDaemon(true);
Thread1.setName("hello");
System.out.println("Starting hello thread...");
Thread1.start();
Runnable bye = new DisplayMessage("Goodbye");
Thread thread2 = new Thread(bye);
Thread2.setPriority(Thread.MIN_PRIORITY);
Thread2.setDaemon(true);
System.out.println("Starting goodbye thread...");
Thread2.start();
System.out.println("Starting thread3...");
Thread thread3 = new GuessANumber(27);
Thread3.start();
Try {
Thread3.join();
} catch (InterruptedException e) {
System.out.println("Thread interrupted.");
}
System.out.println("Starting thread4...");
Thread thread4 = new GuessANumber(75);
Thread4.start();
System.out.println("main() is ending...");
}
}
This will produce the following result. You can try this example again and again and you will get a different result every time.
Output
Starting hello thread...
Starting goodbye thread...
Hello
Hello
Hello
Hello
Hello
Hello
Goodbye
Goodbye
Goodbye
Goodbye
Goodbye
.......
Q7) Describe a runnable interface in java with example?
A7) java.lang. Runnable is an interface that a class must implement if its instances are to be executed by a thread. Subclass Thread and implement Runnable are two techniques to start a new Thread. When a task can be accomplished by overriding simply the run() function of Runnable, there is no need to subclass Thread.
Steps to create a new Thread using Runnable
● Make a Runnable implementer and use it to call the run() method.
● Create a Thread object and pass the implementer to it; Thread has a function Object() { [native code] } that takes Runnable objects.
● Invoke the Thread instance's start() method, which runs the implementer's run() method inside. When you call start(), it generates a new Thread that runs the code you wrote in run ().
When you call run() directly, it does not create and start a new Thread; instead, it continues to execute in the same thread. To start a new line of execution, call start() on the thread.
Example
Public class RunnableDemo {
Public static void main(String[] args)
{
System.out.println("Main thread is- "
+ Thread.currentThread().getName());
Thread t1 = new Thread(new RunnableDemo().new RunnableImpl());
t1.start();
}
Private class RunnableImpl implements Runnable {
Public void run()
{
System.out.println(Thread.currentThread().getName()
+ ", executing run() method!");
}
}
}
Output
Main thread is- main
Thread-0, executing run() method!
The main thread executes the main method, while executing start on RunnableImpl produces and starts a new thread, Thread-0.
The Thread Class and the Runnable Interface
Java’s multithreading system is built upon the Thread class, its methods, and its companion interface, Runnable. Thread encapsulates a thread of execution. Since you can’t directly refer to the ethereal state of a running thread, you will deal with it through its proxy, the Thread instance that spawned it. To create a new thread, your program will either extend Thread or implement the Runnable interface.
The Thread class defines several methods that help manage threads. Several of those used in this chapter are shown here:
Thus far, all the examples in this book have used a single thread of execution. The remainder of this chapter explains how to use Thread and Runnable to create and manage threads, beginning with the one thread that all Java programs have: the main thread.
Q8) How to create a thread by implementing a runnable interface?
A8) Create a Thread by Implementing a Runnable Interface
If your class is intended to be executed as a thread then you can achieve this by implementing a Runnable interface. You will need to follow three basic steps −
Step 1
As a first step, you need to implement a run() method provided by a Runnable interface. This method provides an entry point for the thread and you will put your complete business logic inside this method. Following is a simple syntax of the run() method −
Public void run( )
Step 2
As a second step, you will instantiate a Thread object using the following constructor −
Thread(Runnable threadObj, String threadName);
Where, threadObj is an instance of a class that implements the Runnable interface and threadName is the name given to the new thread.
Step 3
Once a Thread object is created, you can start it by calling start() method, which executes a call to run( ) method. Following is a simple syntax of start() method −
Void start();
Q9) What are the states in the lifecycle of a Thread?
A9) A thread can have one of the following states during its lifetime:
- New: In this state, a Thread class object is created using a new operator, but the thread is not alive. Thread doesn't start until we call the start() method.
- Runnable: In this state, the thread is ready to run after calling the start() method. However, the thread is not yet selected by the thread scheduler.
- Running: In this state, the thread scheduler picks the thread from the ready state, and the thread is running.
- Waiting/Blocked: In this state, a thread is not running but still alive, or it is waiting for the other thread to finish.
- Dead/Terminated: A thread is in terminated or dead state when the run() method exits.
Q10) How many types of exceptions are used in java, Explain?
A10) 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.
● User-defined Exception
In Java, we already have some built-in exception classes like ArrayIndexOutOfBoundsException, NullPointerException, and ArithmeticException.
These exceptions are restricted to trigger on some predefined conditions.
In Java, we can write our own exception class by extends the Exception class.
We can throw our own exception on a particular condition using the throw keyword. For creating a user-defined exception, we should have basic knowledge of the try-catch block and throw keyword.
● Built-in Exception
Exceptions that are already available in Java libraries are referred to as built-in exception.
These exceptions are able to define the error situation so that we can understand the reason of getting this error.
It can be categorized into two broad categories,
i.e., checked exceptions and unchecked exception
- Arithmetic Exception: It is thrown when an exceptional condition has occurred in an arithmetic operation.
- Array Index Out of Bounds Exception: It is thrown to indicate that an array has been accessed with an illegal index. The index is either negative or greater than or equal to the size of the array.
- Class Not Found Exception: This Exception is raised when we try to access a class whose definition is not found
- FileNotFoundException: This Exception is raised when a file is not accessible or does not open.
- IOException: It is thrown when an input-output operation failed or interrupted
- InterruptedException: It is thrown when a thread is waiting, sleeping, or doing some processing, and it is interrupted.
- NoSuchFieldException: It is thrown when a class does not contain the field (or variable) specified
- NoSuchMethodException: It is thrown when accessing a method which is not found.
- NullPointerException: This exception is raised when referring to the members of a null object. Null represents nothing
- NumberFormatException: This exception is raised when a method could not convert a string into a numeric format.
- RuntimeException: This represents any exception which occurs during runtime.
- StringIndexOutOfBoundsException: It is thrown by String class methods to indicate that an index is either negative or greater than the size of the string
A) 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 system has shown a compilation error.
B) 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.
Q11) Write any example to create a new thread?
A11) Here is an example that creates a new thread and starts running it −
Class RunnableDemo implements Runnable {
Private Thread t;
Private String threadName;
RunnableDemo( String name) {
ThreadName = name;
System.out.println("Creating " + threadName );
}
Public void run() {
System.out.println("Running " + threadName );
Try {
For(int i = 4; i > 0; i--) {
System.out.println("Thread: " + threadName + ", " + i);
// Let the thread sleep for a while.
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("Thread " + threadName + " interrupted.");
}
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[]) {
RunnableDemo R1 = new RunnableDemo( "Thread-1");
R1.start();
RunnableDemo R2 = new RunnableDemo( "Thread-2");
R2.start();
}
}
This will produce the following result −
Output
Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-1 exiting.
Thread Thread-2 exiting.
Q12) Describe synchronization?
A12) Synchronization in java is the capability to control the access of multiple threads to any shared resource.
Java Synchronization is a better option where we want to allow only one thread to access the shared resource.
When we start two or more threads in a program, it's possible that numerous threads will try to access the same resource, resulting in unexpected results due to concurrency difficulties. For example, if multiple threads try to write to the same file at the same time, the data may be corrupted because one of the threads can override data, or while one thread is opening and another is closing the same file.
As a result, it's necessary to synchronize many threads' actions and ensure that only one thread can access the resource at any given time. This is accomplished through the use of monitors. In Java, each object has its own monitor, which a thread can lock or unlock. On a display, only one thread can retain a lock at a time.
Using synchronized blocks, the Java programming language makes it relatively easy to create threads and synchronize their tasks. Within this block, you retain shared resources. The general form of the synchronized statement is as follows:
Syntax
Synchronized(objectidentifier)
{
// Access shared variables and other shared resources
}
The object identifier is a reference to an object whose lock corresponds to the monitor represented by the synchronized statement. Now we'll look at two different ways to print a counter using two distinct threads. When threads are not synchronized, they publish counter values that are out of order, but when we print counter inside a synchronized() block, it prints counters that are very much in order for both threads.
Multithreading Example with synchronization
Class PrintDemo {
Public void printCount() {
Try {
For(int i = 5; i > 0; i--) {
System.out.println("Counter --- " + i );
}
} catch (Exception e) {
System.out.println("Thread interrupted.");
}
}
}
Class ThreadDemo extends Thread {
Private Thread t;
Private String threadName;
PrintDemo PD;
ThreadDemo( String name, PrintDemo pd) {
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();
// wait for threads to end
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.
Q13) Write any program for synchronized method?
A13) If you declare any method as synchronized, it is known as synchronized method.
Synchronized method is used to lock an object for any shared resource.
When a thread invokes a synchronized method, it automatically acquires the lock for that object and releases it when the thread completes its task.
- //example of java synchronized method
- Class Table{
- Synchronized void printTable(int n){//synchronized method
- For(int i=1;i<=5;i++){
- System.out.println(n*i);
- Try{
- Thread.sleep(400);
- }catch(Exception e){System.out.println(e);}
- }
- }
- }
- Class MyThread1 extends Thread{
- Table t;
- MyThread1(Table t){
- This.t=t;
- }
- Public void run(){
- t.printTable(5);
- }
- }
- Class MyThread2 extends Thread{
- Table t;
- MyThread2(Table t){
- This.t=t;
- }
- Public void run(){
- t.printTable(100);
- }
- }
- Public class TestSynchronization2{
- Public static void main(String args[]){
- Table obj = new Table();//only one object
- MyThread1 t1=new MyThread1(obj);
- MyThread2 t2=new MyThread2(obj);
- t1.start();
- t2.start();
- }
- }
Output: 5
10
15
20
25
100
200
300
400
500
Q14) Define exception handling?
A14) Exception handling
● The Exception Handling in Java is one of the powerful mechanisms to handle the runtime errors so that the normal flow of the application can be maintained.
● In Java, an exception is an event that disrupts the normal flow of the program. It is an object which is thrown at runtime.
What is Exception in Java
Dictionary Meaning: Exception is an abnormal condition.
In Java, an exception is an event that disrupts the normal flow of the program. It is an object which is thrown at runtime.
What is Exception Handling?
Exception Handling is a mechanism to handle runtime errors such as ClassNotFoundException, IOException, SQLException, RemoteException, etc.
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 use exception handling. Let's take a scenario:
- Statement 1;
- Statement 2;
- Statement 3;
- Statement 4;
- Statement 5;//exception occurs
- Statement 6;
- Statement 7;
- Statement 8;
- Statement 9;
- Statement 10;
Suppose there are 10 statements in your program and there occurs an exception at statement 5, the rest of the code will not be executed i.e. statement 6 to 10 will not be executed. If we perform exception handling, the rest of the statement will be executed. That is why we use exception handling in Java.
Q15) Write the types of exceptions?
A15) There are mainly two types of exceptions: checked and unchecked. Here, an error is considered as the unchecked exception. According to Oracle, there are three types of exceptions:
- Checked Exception
- Unchecked Exception
- Error
Fig – Exception handling
There are mainly two types of exceptions: checked and unchecked. An error is considered as the unchecked exception. However, according to Oracle, there are three types of exceptions namely:
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.
1. ClassNotFoundException: The ClassNotFoundException is a kind of checked exception that is thrown when we attempt to use a class that does not exist.
Checked exceptions are those exceptions that are checked by the Java compiler itself.
2. FileNotFoundException: The FileNotFoundException is a checked exception that is thrown when we attempt to access a non-existing file.
3. InterruptedException: InterruptedException is a checked exception that is thrown when a thread is in sleeping or waiting state and another thread attempt to interrupt it.
4. InstantiationException: This exception is also a checked exception that is thrown when we try to create an object of abstract class or interface. That is, an InstantiationException exception occurs when an abstract class or interface is instantiated.
5. IllegalAccessException: The IllegalAccessException is a checked exception and it is thrown when a method is called in another method or class but the calling method or class does not have permission to access that method.
6. CloneNotSupportedException: This checked exception is thrown when we try to clone an object without implementing the cloneable interface.
7. NoSuchFieldException: This is a checked exception that is thrown when an unknown variable is used in a program.
8. NoSuchMethodException: This checked exception is thrown when the undefined method is used in a program.
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.
Let’s see a brief description of them.
1. ArithmeticException: This exception is thrown when arithmetic problems, such as a number is divided by zero, is occurred. That is, it is caused by maths error.
2. ClassCastException: The ClassCastException is a runtime exception that is thrown by JVM when we attempt to invalid typecasting in the program. That is, it is thrown when we cast an object to a subclass of which an object is not an instance.
3. IllegalArgumentException: This runtime exception is thrown by programmatically when an illegal or appropriate argument is passed to call a method. This exception class has further two subclasses:
● Number Format Exception
● Illegal Thread State Exception
Numeric Format Exception: Number Format Exception is thrown by programmatically when we try to convert a string into the numeric type and the process of illegal conversion fails. That is, it occurs due to the illegal conversion of a string to a numeric format.
Illegal Thread State Exception: Illegal Thread State Exception is a runtime exception that is thrown by programmatically when we attempt to perform any operation on a thread but it is incompatible with the current thread state.
4. IndexOutOfBoundsException: This exception class is thrown by JVM when an array or string is going out of the specified index. It has two further subclasses:
● ArrayIndexOutOfBoundsException
● StringIndexOutOfBoundsException
ArrayIndexOutOfBoundsException: ArrayIndexOutOfBoundsException exception is thrown when an array element is accessed out of the index.
StringIndexOutOfBoundsException: StringIndexOutOfBoundsException exception is thrown when a String or StringBuffer element is accessed out of the index.
5. NullPointerException: NullPointerException is a runtime exception that is thrown by JVM when we attempt to use null instead of an object. That is, it is thrown when the reference is null.
6. ArrayStoreException: This exception occurs when we attempt to store any value in an array which is not of array type. For example, suppose, an array is of integer type but we are trying to store a value of an element of another type.
7. IllegalStateException: The IllegalStateException exception is thrown by programmatically when the runtime environment is not in an appropriate state for calling any method.
8. IllegalMonitorStateException: This exception is thrown when a thread does not have the right to monitor an object and tries to access wait(), notify(), and notifyAll() methods of the object.
9. NegativeArraySizeException: The NegativeArraySizeException exception is thrown when an array is created with a negative size.
3) Error
Error is irrecoverable. Some examples of errors are Out Of Memory Error, Virtual Machine Error, Assertion Error etc.
Q16) What are the differences between checked and unchecked exceptions?
A16) Difference between Checked and Unchecked Exceptions
Checked Exception | Unchecked Exception |
These exceptions are checked at compile time. These exceptions are handled at compile time too. | These exceptions are just opposite to the checked exceptions. These exceptions are not checked and handled at compile time. |
These exceptions are direct subclasses of exception but not extended from RuntimeException class. | They are the direct subclasses of the RuntimeException class. |
The code gives a compilation error in the case when a method throws a checked exception. The compiler is not able to handle the exception on its own. | The code compiles without any error because the exceptions escape the notice of the compiler. These exceptions are the results of user-created errors in programming logic. |
These exceptions mostly occur when the probability of failure is too high. | These exceptions occur mostly due to programming mistakes. |
Common checked exceptions include IOException, DataAccessException, InterruptedException, etc. | Common unchecked exceptions include ArithmeticException, InvalidClassException, NullPointerException, etc. |
These exceptions are propagated using the throws keyword. | These are automatically propagated. |
It is required to provide the try-catch and try-finally block to handle the checked exception. | In the case of unchecked exception it is not mandatory. |
Q17) Explain try and catch?
A17) Java try block
Java try block is used to enclose the code that might throw an exception. It must be used within the method.
If an exception occurs at the particular statement of try block, the rest of the block code will not execute. So, it is recommended not to keeping the code in try block that will not throw an exception.
Java try block must be followed by either catch or finally block.
Syntax of Java try-catch
- 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.
Problem without exception handling
Let's try to understand the problem if we don't use a try-catch block.
Example 1
- Public class TryCatchExample1 {
- Public static void main(String[] args) {
- Int data=50/0; //may throw exception
- System.out.println("rest of the code");
- }
- }
Output:
Exception in thread "main" java.lang.ArithmeticException: / by zero
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 can be 100 lines of code after exception. So all the code after exception will not be executed.
Java Multi-catch block
A try block can be followed by one or more 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.
Points to remember
● At a time only one exception occurs and at a time only one catch block is executed.
● 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.
- Public class MultipleCatchBlock1 {
- Public static void main(String[] args) {
- Try{
- Int a[]=new int[5];
- a[5]=30/0;
- }
- Catch(ArithmeticException e)
- {
- System.out.println("Arithmetic Exception occurs");
- }
- Catch(ArrayIndexOutOfBoundsException e)
- {
- System.out.println("ArrayIndexOutOfBounds Exception occurs");
- }
- Catch(Exception e)
- {
- System.out.println("Parent Exception occurs");
- }
- System.out.println("rest of the code");
- }
- }
Output:
Arithmetic Exception occurs
Rest of the code
Q18) Describe throw, throws and finally with example?
A18) Java throw keyword
The Java throw keyword is used to explicitly throw an exception.
We can throw either checked or unchecked exception in java by throw keyword. The throw keyword is mainly used to throw custom exception. We will see custom exceptions later.
The syntax of java throw keyword is given below.
- Throw exception;
Let's see the example of throw IOException.
- Throw new IOException("sorry device error);
Java throw keyword example
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.
- Public class TestThrow1{
- Static void validate(int age){
- If(age<18)
- Throw new ArithmeticException("not valid");
- Else
- System.out.println("welcome to vote");
- }
- Public static void main(String args[]){
- Validate(13);
- System.out.println("rest of the code...");
- }
- }
Output:
Exception in thread main java.lang.ArithmeticException:not valid
Java throws keyword
The Java throws keyword is used to declare an exception. It gives 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 normal flow 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 performing check up before the code being used.
Syntax of java throws
- Return_type method_name() throws exception_class_name{
- //method code
- }
Java throws example
Let's see the example of java throws clause which describes that checked exceptions can be propagated by throws keyword.
- Import java.io.IOException;
- Class Testthrows1{
- Void m()throws IOException{
- Throw new IOException("device error");//checked exception
- }
- Void n()throws IOException{
- m();
- }
- Void p(){
- Try{
- n();
- }catch(Exception e){System.out.println("exception handled");}
- }
- Public static void main(String args[]){
- Testthrows1 obj=new Testthrows1();
- Obj.p();
- System.out.println("normal flow...");
- }
- }
Output:
Exception handled
Normal flow...
Java finally block
Java finally block is a block that is used to execute important code such as closing connection, stream etc.
Java finally block is always executed whether exception is handled or not.
Fig - Java finally block follows try or catch block.
Note: If you don't handle exception, before terminating the program, JVM executes finally block(if any).
Why use java finally
● Finally block in java can be used to put "cleanup" code such as closing a file, closing connection etc.
Usage of Java finally
Let's see the different cases where java finally block can be used.
Case 1
Let's see the java finally example where exception doesn't occur.
- Class TestFinallyBlock{
- Public static void main(String args[]){
- Try{
- Int data=25/5;
- System.out.println(data);
- }
- Catch(NullPointerException e){System.out.println(e);}
- Finally{System.out.println("finally block is always executed");}
- System.out.println("rest of the code...");
- }
- }
Output:5
Finally block is always executed
Rest of the code...
Q19) Write the difference between throw and throws?
A19) Difference between throw and throws in Java
There are many differences between throw and throws keywords. A list of differences between throw and throws are given below:
No. | Throw | Throws |
1) | Java throw keyword is used to explicitly throw an exception. | Java throws keyword is used to declare an exception. |
2) | Checked exception cannot be propagated using throw only. | Checked exception can be propagated with throws. |
3) | Throw is followed by an instance. | Throws is followed by class. |
4) | Throw is used within the method. | Throws is used with the method signature. |
5) | You cannot throw multiple exceptions. | You can declare multiple exceptions e.g. |
Q20) What is the difference between final, finally and finalize?
A20) Difference between final, finally and finalize
There are many differences between final, finally and finalize. A list of differences between final, finally and finalize are given below:
Key | Final | Finally | Finalize |
Definition | Final is the keyword and access modifier which is used to apply restrictions on a class, method or variable. | Finally is the block in Java Exception Handling to execute the important code whether the exception occurs or not. | Finalize is the method in Java which is used to perform clean up processing just before object is garbage collected. |
Applicable to | Final keyword is used with the classes, methods and variables. | Finally block is always related to the try and catch block in exception handling. | Finalize() method is used with the objects. |
Functionality | (1) Once declared, final variable becomes constant and cannot be modified. (2) final method cannot be overridden by sub class. (3) final class cannot be inherited. | (1) finally block runs the important code even if exception occurs or not. (2) finally block cleans up all the resources used in try block | Finalize method performs the cleaning activities with respect to the object before its destruction. |
Execution | Final method is executed only when we call it. | Finally block is executed as soon as the try-catch block is executed. It's execution is not dependant on the exception. | Finalize method is executed just before the object is destroyed. |
Q21) Write a program where an exception occurs?
A21) Program if exception occurs
- 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:
Runtime Exception
Unit - 5
Unit - 5
Multithreading in Java
Q1) Write short notes on multithreading?
A1) Multithreading
In Java, multithreading is the process of running several threads at the same time.
A thread is the smallest unit of processing and is a lightweight sub-process. Multitasking is accomplished through the use of multiprocessing and multithreading.
Because threads share memory, we employ multithreading rather than multiprocessing. They conserve memory by not allocating a separate memory space, and context-switching between threads takes less time than processing.
Multithreading in Java is typically utilized in gaming, animation, and other similar applications.
Because Java is a multi-threaded programming language, we can use it to create multi-threaded programs. A multi-threaded program is made up of two or more portions that can operate in parallel, each of which can tackle a distinct task at the same time, maximizing the use of available resources, especially when your computer has several CPUs.
Multitasking is defined as the sharing of common processing resources, such as a CPU, by many processes. Multi-threading extends the concept of multitasking into programs by allowing you to divide certain operations within a single app into several threads. Each thread can execute in its own thread. Not only does the operating system split processing time among distinct apps, but it also divides it among each thread within an application.
Multi-threading allows you to write software in which multiple activities can run at the same time.
Q2) Explain the Java Thread Model?
A2) Threads exist in several states. A thread can be running. It can be ready to run as soon as it gets CPU time. A running thread can be suspended, which temporarily halts its activity. A suspended thread can then be resumed, allowing it to pick up where it left off. A thread can be blocked when waiting for a resource. At any time, a thread can be terminated, which halts its execution immediately. Once terminated, a thread cannot be resumed.
Life Cycle of a Thread
A thread goes through various stages in its life cycle. For example, a thread is born, started, runs, and then dies. The following diagram shows the complete life cycle of a thread.
Fig - The complete life cycle of a thread
Following are the stages of the life cycle −
● 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.
● Runnable − After a newly born thread is started, the thread becomes runnable. A thread in this state is considered to be executing its task.
● Waiting − Sometimes, a thread transitions to the waiting state while the thread waits for another thread to perform a task. A thread transitions back to the runnable state only when another thread signals the waiting thread to continue executing.
● Timed Waiting − A runnable thread can enter the timed waiting state for a specified interval of time. A thread in this state transitions back to the runnable state when that time interval expires or when the event it is waiting for occurs.
● Terminated (Dead) − A runnable thread enters the terminated state when it completes its task or otherwise terminates.
Q3) Explain Thread Priorities in java?
A3) Java assigns to each thread a priority that determines how that thread should be treated with respect to the others. Thread priorities are integers that specify the relative priority of one thread to another. As an absolute value, a priority is meaningless; a higher-priority thread doesn’t run any faster than a lower-priority thread if it is the only thread running.
Instead, a thread’s priority is used to decide when to switch from one running thread to the next. This is called a context switch. The rules that determine when a context switch takes place are simple:
A thread can voluntarily relinquish control. This is done by explicitly yielding, sleeping, or blocking on pending I/O. In this scenario, all other threads are examined, and the highest-priority thread that is ready to run is given the CPU.
A thread can be preempted by a higher-priority thread. In this case, a lower-priority thread that does not yield the processor is simply preempted—no matter what it is doing— by a higher-priority thread. Basically, as soon as a higher-priority thread wants to run, it does. This is called preemptive multitasking.
In cases where two threads with the same priority are competing for CPU cycles, the situation is a bit complicated. For operating systems such as Windows, threads of equal priority are time-sliced automatically in round-robin fashion. For other types of operating systems, threads of equal priority must voluntarily yield control to their peers. If they don’t, the other threads will not run.
Q4) What is synchronization and messaging in java?
A4) Synchronization
Because multithreading introduces an asynchronous behavior to your programs, there must be a way for you to enforce synchronicity when you need it. For example, if you want two threads to communicate and share a complicated data structure, such as a linked list, you need some way to ensure that they don’t conflict with each other. That is, you must prevent one thread from writing data while another thread is in the middle of reading it.
For this purpose, Java implements an elegant twist on an age-old model of interprocess synchronization: the monitor. The monitor is a control mechanism first defined by C.A.R. Hoare. You can think of a monitor as a very small box that can hold only one thread. Once a thread enters a monitor, all other threads must wait until that thread exits the monitor. In this way, a monitor can be used to protect a shared asset from being manipulated by more than one thread at a time.
In Java, there is no class “Monitor”; instead, each object has its own implicit monitor that is automatically entered when one of the object’s synchronized methods is called. Once a thread is inside a synchronized method, no other thread can call any other synchronized method on the same object. This enables you to write very clear and concise multithreaded code, because synchronization support is built into the language.
Messaging
After you divide your program into separate threads, you need to define how they will communicate with each other. When programming with some other languages, you must depend on the operating system to establish communication between threads. This, of course, adds overhead. By contrast, Java provides a clean, low-cost way for two or more threads to talk to each other, via calls to predefined methods that all objects have. Java’s messaging system allows a thread to enter a synchronized method on an object, and then wait there until some other thread explicitly notifies it to come out.
Q5) What are thread methods?
A5) Following is the list of important methods available in the Thread class.
Sr.No. | Method & Description |
1 | Public void start() Starts the thread in a separate path of execution, then invokes the run() method on this Thread object. |
2 | Public void run() If this Thread object was instantiated using a separate Runnable target, the run() method is invoked on that Runnable object. |
3 | Public final void setName(String name) Changes the name of the Thread object. There is also a getName() method for retrieving the name. |
4 | Public final void setPriority(int priority) Sets the priority of this Thread object. The possible values are between 1 and 10. |
5 | Public final void setDaemon(boolean on) A parameter of true denotes this Thread as a daemon thread. |
6 | Public final void join(long millisec) The current thread invokes this method on a second thread, causing the current thread to block until the second thread terminates or the specified number of milliseconds passes. |
7 | Public void interrupt() Interrupts this thread, causing it to continue execution if it was blocked for any reason. |
8 | Public final boolean isAlive() Returns true if the thread is alive, which is any time after the thread has been started but before it runs to completion. |
The previous methods are invoked on a particular Thread object. The following methods in the Thread class are static. Invoking one of the static methods performs the operation on the currently running thread.
Sr.No. | Method & Description |
1 | Public static void yield() Causes the currently running thread to yield to any other threads of the same priority that are waiting to be scheduled. |
2 | Public static void sleep(long millisec) Causes the currently running thread to block for at least the specified number of milliseconds. |
3 | Public static boolean holdsLock(Object x) Returns true if the current thread holds the lock on the given Object. |
4 | Public static Thread currentThread() Returns a reference to the currently running thread, which is the thread that invokes this method. |
5 | Public static void dumpStack() Prints the stack trace for the currently running thread, which is useful when debugging a multithreaded application. |
Q6) Write any example of thread?
A6) The following Thread Class Demo program demonstrates some of these methods of the Thread class. Consider a class Display Message which implements Runnable −
// File Name : DisplayMessage.java
// Create a thread to implement Runnable
Public class DisplayMessage implements Runnable {
Private String message;
Public DisplayMessage(String message) {
This.message = message;
}
Public void run() {
While(true) {
System.out.println(message);
}
}
}
Following is another class which extends the Thread class −
// File Name : GuessANumber.java
// Create a thread to extend Thread
Public class GuessANumber extends Thread {
Private int number;
Public GuessANumber(int number) {
This.number = number;
}
Public void run() {
Int counter = 0;
Int guess = 0;
Do {
Guess = (int) (Math.random() * 100 + 1);
System.out.println(this.getName() + " guesses " + guess);
Counter++;
} while(guess != number);
System.out.println("** Correct!" + this.getName() + "in" + counter + "guesses.**");
}
}
Following is the main program, which makes use of the above-defined classes −
// File Name : ThreadClassDemo.java
Public class ThreadClassDemo {
Public static void main(String [] args) {
Runnable hello = new DisplayMessage("Hello");
Thread thread1 = new Thread(hello);
Thread1.setDaemon(true);
Thread1.setName("hello");
System.out.println("Starting hello thread...");
Thread1.start();
Runnable bye = new DisplayMessage("Goodbye");
Thread thread2 = new Thread(bye);
Thread2.setPriority(Thread.MIN_PRIORITY);
Thread2.setDaemon(true);
System.out.println("Starting goodbye thread...");
Thread2.start();
System.out.println("Starting thread3...");
Thread thread3 = new GuessANumber(27);
Thread3.start();
Try {
Thread3.join();
} catch (InterruptedException e) {
System.out.println("Thread interrupted.");
}
System.out.println("Starting thread4...");
Thread thread4 = new GuessANumber(75);
Thread4.start();
System.out.println("main() is ending...");
}
}
This will produce the following result. You can try this example again and again and you will get a different result every time.
Output
Starting hello thread...
Starting goodbye thread...
Hello
Hello
Hello
Hello
Hello
Hello
Goodbye
Goodbye
Goodbye
Goodbye
Goodbye
.......
Q7) Describe a runnable interface in java with example?
A7) java.lang. Runnable is an interface that a class must implement if its instances are to be executed by a thread. Subclass Thread and implement Runnable are two techniques to start a new Thread. When a task can be accomplished by overriding simply the run() function of Runnable, there is no need to subclass Thread.
Steps to create a new Thread using Runnable
● Make a Runnable implementer and use it to call the run() method.
● Create a Thread object and pass the implementer to it; Thread has a function Object() { [native code] } that takes Runnable objects.
● Invoke the Thread instance's start() method, which runs the implementer's run() method inside. When you call start(), it generates a new Thread that runs the code you wrote in run ().
When you call run() directly, it does not create and start a new Thread; instead, it continues to execute in the same thread. To start a new line of execution, call start() on the thread.
Example
Public class RunnableDemo {
Public static void main(String[] args)
{
System.out.println("Main thread is- "
+ Thread.currentThread().getName());
Thread t1 = new Thread(new RunnableDemo().new RunnableImpl());
t1.start();
}
Private class RunnableImpl implements Runnable {
Public void run()
{
System.out.println(Thread.currentThread().getName()
+ ", executing run() method!");
}
}
}
Output
Main thread is- main
Thread-0, executing run() method!
The main thread executes the main method, while executing start on RunnableImpl produces and starts a new thread, Thread-0.
The Thread Class and the Runnable Interface
Java’s multithreading system is built upon the Thread class, its methods, and its companion interface, Runnable. Thread encapsulates a thread of execution. Since you can’t directly refer to the ethereal state of a running thread, you will deal with it through its proxy, the Thread instance that spawned it. To create a new thread, your program will either extend Thread or implement the Runnable interface.
The Thread class defines several methods that help manage threads. Several of those used in this chapter are shown here:
Thus far, all the examples in this book have used a single thread of execution. The remainder of this chapter explains how to use Thread and Runnable to create and manage threads, beginning with the one thread that all Java programs have: the main thread.
Q8) How to create a thread by implementing a runnable interface?
A8) Create a Thread by Implementing a Runnable Interface
If your class is intended to be executed as a thread then you can achieve this by implementing a Runnable interface. You will need to follow three basic steps −
Step 1
As a first step, you need to implement a run() method provided by a Runnable interface. This method provides an entry point for the thread and you will put your complete business logic inside this method. Following is a simple syntax of the run() method −
Public void run( )
Step 2
As a second step, you will instantiate a Thread object using the following constructor −
Thread(Runnable threadObj, String threadName);
Where, threadObj is an instance of a class that implements the Runnable interface and threadName is the name given to the new thread.
Step 3
Once a Thread object is created, you can start it by calling start() method, which executes a call to run( ) method. Following is a simple syntax of start() method −
Void start();
Q9) What are the states in the lifecycle of a Thread?
A9) A thread can have one of the following states during its lifetime:
- New: In this state, a Thread class object is created using a new operator, but the thread is not alive. Thread doesn't start until we call the start() method.
- Runnable: In this state, the thread is ready to run after calling the start() method. However, the thread is not yet selected by the thread scheduler.
- Running: In this state, the thread scheduler picks the thread from the ready state, and the thread is running.
- Waiting/Blocked: In this state, a thread is not running but still alive, or it is waiting for the other thread to finish.
- Dead/Terminated: A thread is in terminated or dead state when the run() method exits.
Q10) How many types of exceptions are used in java, Explain?
A10) 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.
● User-defined Exception
In Java, we already have some built-in exception classes like ArrayIndexOutOfBoundsException, NullPointerException, and ArithmeticException.
These exceptions are restricted to trigger on some predefined conditions.
In Java, we can write our own exception class by extends the Exception class.
We can throw our own exception on a particular condition using the throw keyword. For creating a user-defined exception, we should have basic knowledge of the try-catch block and throw keyword.
● Built-in Exception
Exceptions that are already available in Java libraries are referred to as built-in exception.
These exceptions are able to define the error situation so that we can understand the reason of getting this error.
It can be categorized into two broad categories,
i.e., checked exceptions and unchecked exception
- Arithmetic Exception: It is thrown when an exceptional condition has occurred in an arithmetic operation.
- Array Index Out of Bounds Exception: It is thrown to indicate that an array has been accessed with an illegal index. The index is either negative or greater than or equal to the size of the array.
- Class Not Found Exception: This Exception is raised when we try to access a class whose definition is not found
- FileNotFoundException: This Exception is raised when a file is not accessible or does not open.
- IOException: It is thrown when an input-output operation failed or interrupted
- InterruptedException: It is thrown when a thread is waiting, sleeping, or doing some processing, and it is interrupted.
- NoSuchFieldException: It is thrown when a class does not contain the field (or variable) specified
- NoSuchMethodException: It is thrown when accessing a method which is not found.
- NullPointerException: This exception is raised when referring to the members of a null object. Null represents nothing
- NumberFormatException: This exception is raised when a method could not convert a string into a numeric format.
- RuntimeException: This represents any exception which occurs during runtime.
- StringIndexOutOfBoundsException: It is thrown by String class methods to indicate that an index is either negative or greater than the size of the string
A) 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 system has shown a compilation error.
B) 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.
Q11) Write any example to create a new thread?
A11) Here is an example that creates a new thread and starts running it −
Class RunnableDemo implements Runnable {
Private Thread t;
Private String threadName;
RunnableDemo( String name) {
ThreadName = name;
System.out.println("Creating " + threadName );
}
Public void run() {
System.out.println("Running " + threadName );
Try {
For(int i = 4; i > 0; i--) {
System.out.println("Thread: " + threadName + ", " + i);
// Let the thread sleep for a while.
Thread.sleep(50);
}
} catch (InterruptedException e) {
System.out.println("Thread " + threadName + " interrupted.");
}
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[]) {
RunnableDemo R1 = new RunnableDemo( "Thread-1");
R1.start();
RunnableDemo R2 = new RunnableDemo( "Thread-2");
R2.start();
}
}
This will produce the following result −
Output
Creating Thread-1
Starting Thread-1
Creating Thread-2
Starting Thread-2
Running Thread-1
Thread: Thread-1, 4
Running Thread-2
Thread: Thread-2, 4
Thread: Thread-1, 3
Thread: Thread-2, 3
Thread: Thread-1, 2
Thread: Thread-2, 2
Thread: Thread-1, 1
Thread: Thread-2, 1
Thread Thread-1 exiting.
Thread Thread-2 exiting.
Q12) Describe synchronization?
A12) Synchronization in java is the capability to control the access of multiple threads to any shared resource.
Java Synchronization is a better option where we want to allow only one thread to access the shared resource.
When we start two or more threads in a program, it's possible that numerous threads will try to access the same resource, resulting in unexpected results due to concurrency difficulties. For example, if multiple threads try to write to the same file at the same time, the data may be corrupted because one of the threads can override data, or while one thread is opening and another is closing the same file.
As a result, it's necessary to synchronize many threads' actions and ensure that only one thread can access the resource at any given time. This is accomplished through the use of monitors. In Java, each object has its own monitor, which a thread can lock or unlock. On a display, only one thread can retain a lock at a time.
Using synchronized blocks, the Java programming language makes it relatively easy to create threads and synchronize their tasks. Within this block, you retain shared resources. The general form of the synchronized statement is as follows:
Syntax
Synchronized(objectidentifier)
{
// Access shared variables and other shared resources
}
The object identifier is a reference to an object whose lock corresponds to the monitor represented by the synchronized statement. Now we'll look at two different ways to print a counter using two distinct threads. When threads are not synchronized, they publish counter values that are out of order, but when we print counter inside a synchronized() block, it prints counters that are very much in order for both threads.
Multithreading Example with synchronization
Class PrintDemo {
Public void printCount() {
Try {
For(int i = 5; i > 0; i--) {
System.out.println("Counter --- " + i );
}
} catch (Exception e) {
System.out.println("Thread interrupted.");
}
}
}
Class ThreadDemo extends Thread {
Private Thread t;
Private String threadName;
PrintDemo PD;
ThreadDemo( String name, PrintDemo pd) {
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();
// wait for threads to end
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.
Q13) Write any program for synchronized method?
A13) If you declare any method as synchronized, it is known as synchronized method.
Synchronized method is used to lock an object for any shared resource.
When a thread invokes a synchronized method, it automatically acquires the lock for that object and releases it when the thread completes its task.
- //example of java synchronized method
- Class Table{
- Synchronized void printTable(int n){//synchronized method
- For(int i=1;i<=5;i++){
- System.out.println(n*i);
- Try{
- Thread.sleep(400);
- }catch(Exception e){System.out.println(e);}
- }
- }
- }
- Class MyThread1 extends Thread{
- Table t;
- MyThread1(Table t){
- This.t=t;
- }
- Public void run(){
- t.printTable(5);
- }
- }
- Class MyThread2 extends Thread{
- Table t;
- MyThread2(Table t){
- This.t=t;
- }
- Public void run(){
- t.printTable(100);
- }
- }
- Public class TestSynchronization2{
- Public static void main(String args[]){
- Table obj = new Table();//only one object
- MyThread1 t1=new MyThread1(obj);
- MyThread2 t2=new MyThread2(obj);
- t1.start();
- t2.start();
- }
- }
Output: 5
10
15
20
25
100
200
300
400
500
Q14) Define exception handling?
A14) Exception handling
● The Exception Handling in Java is one of the powerful mechanisms to handle the runtime errors so that the normal flow of the application can be maintained.
● In Java, an exception is an event that disrupts the normal flow of the program. It is an object which is thrown at runtime.
What is Exception in Java
Dictionary Meaning: Exception is an abnormal condition.
In Java, an exception is an event that disrupts the normal flow of the program. It is an object which is thrown at runtime.
What is Exception Handling?
Exception Handling is a mechanism to handle runtime errors such as ClassNotFoundException, IOException, SQLException, RemoteException, etc.
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 use exception handling. Let's take a scenario:
- Statement 1;
- Statement 2;
- Statement 3;
- Statement 4;
- Statement 5;//exception occurs
- Statement 6;
- Statement 7;
- Statement 8;
- Statement 9;
- Statement 10;
Suppose there are 10 statements in your program and there occurs an exception at statement 5, the rest of the code will not be executed i.e. statement 6 to 10 will not be executed. If we perform exception handling, the rest of the statement will be executed. That is why we use exception handling in Java.
Q15) Write the types of exceptions?
A15) There are mainly two types of exceptions: checked and unchecked. Here, an error is considered as the unchecked exception. According to Oracle, there are three types of exceptions:
- Checked Exception
- Unchecked Exception
- Error
Fig – Exception handling
There are mainly two types of exceptions: checked and unchecked. An error is considered as the unchecked exception. However, according to Oracle, there are three types of exceptions namely:
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.
1. ClassNotFoundException: The ClassNotFoundException is a kind of checked exception that is thrown when we attempt to use a class that does not exist.
Checked exceptions are those exceptions that are checked by the Java compiler itself.
2. FileNotFoundException: The FileNotFoundException is a checked exception that is thrown when we attempt to access a non-existing file.
3. InterruptedException: InterruptedException is a checked exception that is thrown when a thread is in sleeping or waiting state and another thread attempt to interrupt it.
4. InstantiationException: This exception is also a checked exception that is thrown when we try to create an object of abstract class or interface. That is, an InstantiationException exception occurs when an abstract class or interface is instantiated.
5. IllegalAccessException: The IllegalAccessException is a checked exception and it is thrown when a method is called in another method or class but the calling method or class does not have permission to access that method.
6. CloneNotSupportedException: This checked exception is thrown when we try to clone an object without implementing the cloneable interface.
7. NoSuchFieldException: This is a checked exception that is thrown when an unknown variable is used in a program.
8. NoSuchMethodException: This checked exception is thrown when the undefined method is used in a program.
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.
Let’s see a brief description of them.
1. ArithmeticException: This exception is thrown when arithmetic problems, such as a number is divided by zero, is occurred. That is, it is caused by maths error.
2. ClassCastException: The ClassCastException is a runtime exception that is thrown by JVM when we attempt to invalid typecasting in the program. That is, it is thrown when we cast an object to a subclass of which an object is not an instance.
3. IllegalArgumentException: This runtime exception is thrown by programmatically when an illegal or appropriate argument is passed to call a method. This exception class has further two subclasses:
● Number Format Exception
● Illegal Thread State Exception
Numeric Format Exception: Number Format Exception is thrown by programmatically when we try to convert a string into the numeric type and the process of illegal conversion fails. That is, it occurs due to the illegal conversion of a string to a numeric format.
Illegal Thread State Exception: Illegal Thread State Exception is a runtime exception that is thrown by programmatically when we attempt to perform any operation on a thread but it is incompatible with the current thread state.
4. IndexOutOfBoundsException: This exception class is thrown by JVM when an array or string is going out of the specified index. It has two further subclasses:
● ArrayIndexOutOfBoundsException
● StringIndexOutOfBoundsException
ArrayIndexOutOfBoundsException: ArrayIndexOutOfBoundsException exception is thrown when an array element is accessed out of the index.
StringIndexOutOfBoundsException: StringIndexOutOfBoundsException exception is thrown when a String or StringBuffer element is accessed out of the index.
5. NullPointerException: NullPointerException is a runtime exception that is thrown by JVM when we attempt to use null instead of an object. That is, it is thrown when the reference is null.
6. ArrayStoreException: This exception occurs when we attempt to store any value in an array which is not of array type. For example, suppose, an array is of integer type but we are trying to store a value of an element of another type.
7. IllegalStateException: The IllegalStateException exception is thrown by programmatically when the runtime environment is not in an appropriate state for calling any method.
8. IllegalMonitorStateException: This exception is thrown when a thread does not have the right to monitor an object and tries to access wait(), notify(), and notifyAll() methods of the object.
9. NegativeArraySizeException: The NegativeArraySizeException exception is thrown when an array is created with a negative size.
3) Error
Error is irrecoverable. Some examples of errors are Out Of Memory Error, Virtual Machine Error, Assertion Error etc.
Q16) What are the differences between checked and unchecked exceptions?
A16) Difference between Checked and Unchecked Exceptions
Checked Exception | Unchecked Exception |
These exceptions are checked at compile time. These exceptions are handled at compile time too. | These exceptions are just opposite to the checked exceptions. These exceptions are not checked and handled at compile time. |
These exceptions are direct subclasses of exception but not extended from RuntimeException class. | They are the direct subclasses of the RuntimeException class. |
The code gives a compilation error in the case when a method throws a checked exception. The compiler is not able to handle the exception on its own. | The code compiles without any error because the exceptions escape the notice of the compiler. These exceptions are the results of user-created errors in programming logic. |
These exceptions mostly occur when the probability of failure is too high. | These exceptions occur mostly due to programming mistakes. |
Common checked exceptions include IOException, DataAccessException, InterruptedException, etc. | Common unchecked exceptions include ArithmeticException, InvalidClassException, NullPointerException, etc. |
These exceptions are propagated using the throws keyword. | These are automatically propagated. |
It is required to provide the try-catch and try-finally block to handle the checked exception. | In the case of unchecked exception it is not mandatory. |
Q17) Explain try and catch?
A17) Java try block
Java try block is used to enclose the code that might throw an exception. It must be used within the method.
If an exception occurs at the particular statement of try block, the rest of the block code will not execute. So, it is recommended not to keeping the code in try block that will not throw an exception.
Java try block must be followed by either catch or finally block.
Syntax of Java try-catch
- 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.
Problem without exception handling
Let's try to understand the problem if we don't use a try-catch block.
Example 1
- Public class TryCatchExample1 {
- Public static void main(String[] args) {
- Int data=50/0; //may throw exception
- System.out.println("rest of the code");
- }
- }
Output:
Exception in thread "main" java.lang.ArithmeticException: / by zero
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 can be 100 lines of code after exception. So all the code after exception will not be executed.
Java Multi-catch block
A try block can be followed by one or more 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.
Points to remember
● At a time only one exception occurs and at a time only one catch block is executed.
● 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.
- Public class MultipleCatchBlock1 {
- Public static void main(String[] args) {
- Try{
- Int a[]=new int[5];
- a[5]=30/0;
- }
- Catch(ArithmeticException e)
- {
- System.out.println("Arithmetic Exception occurs");
- }
- Catch(ArrayIndexOutOfBoundsException e)
- {
- System.out.println("ArrayIndexOutOfBounds Exception occurs");
- }
- Catch(Exception e)
- {
- System.out.println("Parent Exception occurs");
- }
- System.out.println("rest of the code");
- }
- }
Output:
Arithmetic Exception occurs
Rest of the code
Q18) Describe throw, throws and finally with example?
A18) Java throw keyword
The Java throw keyword is used to explicitly throw an exception.
We can throw either checked or unchecked exception in java by throw keyword. The throw keyword is mainly used to throw custom exception. We will see custom exceptions later.
The syntax of java throw keyword is given below.
- Throw exception;
Let's see the example of throw IOException.
- Throw new IOException("sorry device error);
Java throw keyword example
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.
- Public class TestThrow1{
- Static void validate(int age){
- If(age<18)
- Throw new ArithmeticException("not valid");
- Else
- System.out.println("welcome to vote");
- }
- Public static void main(String args[]){
- Validate(13);
- System.out.println("rest of the code...");
- }
- }
Output:
Exception in thread main java.lang.ArithmeticException:not valid
Java throws keyword
The Java throws keyword is used to declare an exception. It gives 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 normal flow 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 performing check up before the code being used.
Syntax of java throws
- Return_type method_name() throws exception_class_name{
- //method code
- }
Java throws example
Let's see the example of java throws clause which describes that checked exceptions can be propagated by throws keyword.
- Import java.io.IOException;
- Class Testthrows1{
- Void m()throws IOException{
- Throw new IOException("device error");//checked exception
- }
- Void n()throws IOException{
- m();
- }
- Void p(){
- Try{
- n();
- }catch(Exception e){System.out.println("exception handled");}
- }
- Public static void main(String args[]){
- Testthrows1 obj=new Testthrows1();
- Obj.p();
- System.out.println("normal flow...");
- }
- }
Output:
Exception handled
Normal flow...
Java finally block
Java finally block is a block that is used to execute important code such as closing connection, stream etc.
Java finally block is always executed whether exception is handled or not.
Fig - Java finally block follows try or catch block.
Note: If you don't handle exception, before terminating the program, JVM executes finally block(if any).
Why use java finally
● Finally block in java can be used to put "cleanup" code such as closing a file, closing connection etc.
Usage of Java finally
Let's see the different cases where java finally block can be used.
Case 1
Let's see the java finally example where exception doesn't occur.
- Class TestFinallyBlock{
- Public static void main(String args[]){
- Try{
- Int data=25/5;
- System.out.println(data);
- }
- Catch(NullPointerException e){System.out.println(e);}
- Finally{System.out.println("finally block is always executed");}
- System.out.println("rest of the code...");
- }
- }
Output:5
Finally block is always executed
Rest of the code...
Q19) Write the difference between throw and throws?
A19) Difference between throw and throws in Java
There are many differences between throw and throws keywords. A list of differences between throw and throws are given below:
No. | Throw | Throws |
1) | Java throw keyword is used to explicitly throw an exception. | Java throws keyword is used to declare an exception. |
2) | Checked exception cannot be propagated using throw only. | Checked exception can be propagated with throws. |
3) | Throw is followed by an instance. | Throws is followed by class. |
4) | Throw is used within the method. | Throws is used with the method signature. |
5) | You cannot throw multiple exceptions. | You can declare multiple exceptions e.g. |
Q20) What is the difference between final, finally and finalize?
A20) Difference between final, finally and finalize
There are many differences between final, finally and finalize. A list of differences between final, finally and finalize are given below:
Key | Final | Finally | Finalize |
Definition | Final is the keyword and access modifier which is used to apply restrictions on a class, method or variable. | Finally is the block in Java Exception Handling to execute the important code whether the exception occurs or not. | Finalize is the method in Java which is used to perform clean up processing just before object is garbage collected. |
Applicable to | Final keyword is used with the classes, methods and variables. | Finally block is always related to the try and catch block in exception handling. | Finalize() method is used with the objects. |
Functionality | (1) Once declared, final variable becomes constant and cannot be modified. (2) final method cannot be overridden by sub class. (3) final class cannot be inherited. | (1) finally block runs the important code even if exception occurs or not. (2) finally block cleans up all the resources used in try block | Finalize method performs the cleaning activities with respect to the object before its destruction. |
Execution | Final method is executed only when we call it. | Finally block is executed as soon as the try-catch block is executed. It's execution is not dependant on the exception. | Finalize method is executed just before the object is destroyed. |
Q21) Write a program where an exception occurs?
A21) Program if exception occurs
- 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:
Runtime Exception