0% found this document useful (0 votes)
2 views

Thread and Exception Handling

Thread and exception handling java questions

Uploaded by

abdul Muqtadir
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

Thread and Exception Handling

Thread and exception handling java questions

Uploaded by

abdul Muqtadir
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 39

Introduction

An Exception refers to abnormal behaviour of an application that occurs at the time of execution
that could lead to the termination of that application if not handled. Exceptions could include
sudden network errors, database connection errors, errors due to non-existent or corrupt files,
logical errors that were not handled by the developers and many more. Java provides a great way
of handling Exceptions that results in a robust application that does not fail in case of
abnormalities. Due to its importance, exception handling has become a very important and
favourite topic amongst interviewers. Every software developer should know how to handle
unexpected errors while developing an application.

Exception Handling Interview Questions for Freshers

1. What is an exception in Java?

An exception is an abnormal event that disrupts the flow of normal program execution that unless
handled could lead to the termination of that program. In real-world scenarios, a program could
run into an exception if it tries to access a corrupted/non-existent file or if a network error
happens or if the JVM runs out of memory, or if the code is trying to access an index of an array
which does not exist

2. What is exception handling in Java and what are the advantages of exception handling?

Exception Handling is the technique of handling unexpected failures that could occur in a program
so that the program does not terminate and normal execution flow is maintained. Consider an
example program where we have 6 statement blocks as shown in the below image. Statements 1
and 2 execute successfully. While executing the statement 3 block, an unexpected error occurred.
Now the Java program checks if there is any exception-handling mechanism present. If an
exception handling block is present, then the exception is handled gracefully and the program
continues with the execution of the statement 4 block. If not, the program gets terminated.

The following are some of the Advantages of using Exception Handling in Java:

The most important advantage of having an exception-handling technique is that it avoids


abnormal program termination and the normal flow of the program is maintained.

Provides flexibility to the programmers to define/handle what should occur in cases of


failures/errors thereby making the applications more robust and immune to unexpected scenarios.
Provides stable user experience in cases of failures by providing means to let the user know what
made the program fail.

3. How are exceptions handled in Java?

In Java, exceptions could be handled in the following ways:

try-catch block: The try section holds the code that needs to be normally executed and it monitors
for any possible exception that could occur. The catch block “catches” the exception thrown by the
try block. It could consist of logic to handle failure scenario or the catch block could simply rethrow
the exception by using the “throw” keyword.

finally block: Regardless of whether an exception has occurred or not, if we need to execute any
logic, then we place it in the final block that is usually associated with the try-catch block or just
with the try block. The final block is not executed when System.exit(0) is present in either the try
or catch block.

Consider an example where we need to get the value of the score from a file called “resultFile”.
When we access the file, the file could exist and we get the score and everything happens
normally. But there could be cases where the file was accidentally deleted. In this case, when the
program tries to access that file, then it throws FileNotFoundException. There are 2 ways to handle
this exception (Depending on the requirements, we need to choose what way is the most
appropriate for us):-

Case 1: Throw IllegalArgumentException stating the file does not exist as shown in the logic
below.

public int getResultScore(String resultFile) {

try {

Scanner fileContents = new Scanner(new File(resultFile));

return Integer.parseInt(contents.nextLine());

} catch (FileNotFoundException fileNotFound) {

// handle exception by throwing a new exception

throw new IllegalArgumentException("Result file does not exist");

Case 2: Return the score as 0 and log the error that file doesn’t exist as shown in the logic below.

public int getResultScore(String resultFile) {

try {

Scanner fileContents = new Scanner(new File(resultFile));

return Integer.parseInt(contents.nextLine());

} catch (FileNotFoundException fileNotFound) {

// handle exception by returning 0 and logging error


logger.error("Result file does not exist");

return 0;

Finally, irrespective of whether the code running normally or not, we would want to close the
resources. This could run in the finally block as shown below:

public int getResultScore(String resultFile) {

Scanner fileContents;

try {

fileContents = new Scanner(new File(resultFile));

return Integer.parseInt(contents.nextLine());

} catch (FileNotFoundException fileNotFound) {

// handle exception by returning 0 and logging error

logger.error("Result file does not exist");

return 0;

} finally {

if (fileContents != null) {

fileContents.close();

Note:

As of Java 7, the new feature “try-with-resources” helps to autoclose the resources that extend the
“AutoCloseable” interface. The close() method will be called when it exits the try-with-resources
block. For example, the above code which has a close() method call could be simplified as shown
below:

public int getResultScore(String resultFile) {

try (Scanner fileContents = new Scanner(new File(resultFile))) {

return Integer.parseInt(contents.nextLine());

} catch (FileNotFoundException e ) {

// handle exception by returning 0 and logging error

logger.error("Result file does not exist");


return 0;

Sometimes, the program could throw more than 1 exception. In this case, Java supports the usage
of multiple catch blocks. Our example could also encounter a NumberFormatException exception
while parsing integer numbers and this could be handled as shown below:

public int getPlayerScore(String playerFile) {

try (Scanner fileContents = new Scanner(new File(resultFile))) {

return Integer.parseInt(contents.nextLine());

} catch (FileNotFoundException e ) {

// If an exception occurs while opening the file

logger.error("Result file does not exist");

return 0;

} catch (NumberFormatException e) {

// If an exception occurs during parsing the contents to integer format

logger.error("Couldn't format number", e);

return 0;

Multiple catch blocks are useful if we have different exception-handling logic for different types of
exceptions. If our logic of handling the exception is the same (as in the above scenario), then Java7
introduced the feature to union the catch blocks - handle multiple exceptions in the same catch
block. The above could now be simplified to:

public int getPlayerScore(String playerFile) {

try (Scanner fileContents = new Scanner(new File(resultFile))) {

return Integer.parseInt(contents.nextLine());

} catch (FileNotFoundException | NumberFormatException e ) {

//e.getMessage() prints the detailed message

logger.error("Score couldn't be loaded - " + e.getMessage());

return 0;

}
4. What is exception propagation in Java?

Exception propagation is a process where the compiler makes sure that the exception is handled if
it is not handled where it occurs. If an exception is not caught where it occurred, then the
exception goes down the call stack of the preceding method and if it is still not caught there, the
exception propagates further down to the previous method. If the exception is not handled
anywhere in between, the process continues until the exception reaches the bottom of the call
stack. If the exception is still not handled in the last method, i.e, the main method, then the
program gets terminated. Consider an example -

We have a Java program that has a main() method that calls method1() and this method, in turn,
calls another method2(). If an exception occurs in method2() and is not handled, then it is
propagated to method1(). If method1() has an exception handling mechanism, then the
propagation of exception stops and the exception gets handled. The same has been represented in
the image below:

5. What are the important methods defined in Java’s Exception Class?

The throwable class is the base class of Exception. Exception and its subclasses do not provide
specific methods. All the methods that could be used by Exception are defined in the Throwable
class. Some of the most important methods are as follows:

String getMessage(): This method returns the Throwable message of type String. The message
could be given at the time of creating an exception by using the constructor.

String getLocalizedMessage(): This method can be overridden by the Exception and its subclasses
to give locale-specific messages to the calling program. The implementation of this method in the
Throwable class by default uses the getMessage() that returns the exception message. Hence, to
use this method, it should be overridden to avoid this default behaviour.

synchronized Throwable getCause(): This returns the exception cause if it is known. If the cause is
not known, it returns null. The cause is returned if it was provided via the constructors
requiring Throwable or if it was set after the creation of exception by using
the initCause(Throwable) method. Exception and its subclasses may override this method to return
a cause set by different means.

String toString(): This returns the Throwable information in String format consisting of the
Throwable class name and localized message.

void printStackTrace(): As the name indicates, this prints the stack trace data to the standard error
stream. By default, it prints on the console. But, there are overloaded versions of this method
where we can pass either PrintWriter or PrintStream as an argument to write stack trace data to a
specific file or stream.

6. What are runtime exceptions in Java?

Runtime exceptions are those exceptions that occur at the run time of the program execution.
These exceptions are not noticed by the compiler at the compile time and hence the program
successfully gets compiled. Therefore, they are also called unchecked exceptions. All subclasses of
the java.lang.RunTimeException class and java.lang.Error class belongs to runtime exceptions.
Examples of runtime exceptions include NullPointerException, NumberFormatException,
ArrayIndexOutOfBoundException, StackOverflowError, ClassCastException, ArithmeticException,
ConcurrentModificationException, etc.

7. What is the difference between the throw and throws keywords in Java?

The throw keyword allows a programmer to throw an exception object to interrupt normal
program flow. The exception object is handed over to the runtime to handle it. For example, if we
want to signify the status of a task is outdated, we can create an OutdatedTaskException that
extends the Exception class and we can throw this exception object as shown below:

if (task.getStatus().equals("outdated")) {

throw new OutdatedTaskException("Task is outdated");

The throws keyword in Java is used along with the method signature to specify exceptions that the
method could throw during execution. For example, a method could
throw NullPointerException or FileNotFoundException and we can specify that in the method
signature as shown below:

public void someMethod() throws NullPointerException, FileNotFoundException {

// do something

8. How do you handle checked exceptions?

Checked Exceptions can be handled by either using a try-catch block or by using the throws clause
in the method declaration. If these exceptions are not handled properly, then the program would
fail to compile.
9. Differentiate between Checked Exception and Unchecked Exceptions in Java.

The followings programs are the differences between Checked and Unchecked Exceptions:

Checked Exceptions Unchecked Exceptions

These Exceptions are not checked and handled at


These exceptions are checked and handled at the compilation time. They occur during the runtime of
time of compilation. the program and can not be anticipated by the
compiler.

These exceptions are a direct subclass of These exceptions are a direct subclass of
the Exception class. the RuntimeException class.

Program compiles successfully, but the exception


Program would give compilation error if checked
could occur at runtime due to logical errors in the
exceptions are not handled.
program.

Checked Exceptions require handling using a try-


catch block or at least the method should use Unchecked Exceptions do not require try-catch
the throws keyword to let the calling method or throws handling. These exceptions could occur
know that a checked exception could be thrown due to mistakes in programming logic.
from this method.

Examples: ArithmeticException,
Examples: IOException, FileNotFoundException,
ArrayIndexOutOfBoundException,
DataAccessException, InterruptedException, etc.
NullPointerException, InvalidClassException, etc.

10. Can you catch and handle Multiple Exceptions in Java?

There are three ways to handle multiple exceptions in Java:

Since Exception is the base class for all exception types, make use of a catch block that catches the
Exception class-

try {

// do something

} catch (Exception exception) {

// handle exception

However, it is recommended to use accurate Exception handlers instead of generic ones. This is
because having broad exception handlers could make the code error-prone by catching exceptions
that were not anticipated in the software design and could result in unexpected behavior.

From Java 7 onwards, it is now possible to implement multiple catch blocks as shown below -

try {

// do something

} catch (FileNotFoundException fileNotFoundException) {


// handle FileNotFoundException

} catch (EOFException eofException) {

// handle EOFException

When we are using multiple catch blocks, we need to ensure that in a case where the exceptions
have an inheritance relationship, the child exception type should be the first and the parent type
later to avoid a compilation error.

Java 7 also began to provide the usage of multi-catch blocks for reducing duplication of code if the
exception handling logic was similar for different exception types. The syntax of the multi-catch
block is as shown below-

try {

// ...

} catch (FileNotFoundException | EOFException exception) {

// ...

11. What is a stack trace and how is it related to an Exception?

A stack trace is information consisting of names of classes and methods that were invoked right
from the start of program execution to the point where an exception occurred. This is useful to
debug where exactly the exception occurred and due to what reasons. Consider an example stack
trace in Java,

Exception in thread "main" java.lang.NullPointerException

at com.example.demoProject.Book.getBookTitle(Book.java:26)

at com.example.demoProject.Author.getBookTitlesOfAuthor(Author.java:15)

at com.example.demoProject.DemoClass.main(DemoClass.java:14)

To determine where an exception has occurred, we need to check for the beginning of the trace
that has a list of “at …”. In the given example, the exception has occurred at Line Number 26 of
the Book.java class in the getBookTitle() method. We can look at this stack trace and go to the
method and the line number mentioned in the trace and debug for what could have caused the
NullPointerException. Furthermore, we can get to know that the getBookTitle() method in
the Book.java class was called by the getBookTitlesOfAuthor() method in the Author.java class in
Line Number 15 of the file and this in turn was called by the main() method of
the DemoClass.java file in Line Number 14.

12. What is Exception Chaining?

Exception Chaining happens when one exception is thrown due to another exception. This helps
developers to identify under what situation an Exception was thrown that in turn caused another
Exception in the program. For example, we have a method that reads two numbers and then
divides them. The method throws ArithmeticException when we divide a number by zero. While
retrieving the denominator number from the array, there might have been an IOException that
prompted to return of the number as 0 that resulted in ArithmeticException. The original root
cause in this scenario was the IOException. The method caller would not know this case and they
assume the exception was due to dividing a number by 0. Chained Exceptions are very useful in
such cases. This was introduced in JDK 1.4.

13. Can we have statements between try, catch and finally blocks?

No. This is because they form a single unit.

14. How are the keywords final, finally and finalize different from each other?

final keyword: By using this keyword,

we can declare a variable as final (meaning, variable value cannot be changed).

we can declare a method as final (meaning, that method cannot be overridden).

we can declare a class as final (meaning, that class cannot be extended).

finally keyword: This is used in conjunction with the try-catch block or the try block where we
want to run some logic whether or not an exception has occurred.

finalize keyword: This is a method called by the Garbage Collector just before destroying the
objects no longer needed in the program.

15. What is the output of this below program?

public class TestClass

public static void main(String[] args)

int a = 30;

int b = 40;

int c = 10;

int expression = (a * b)/(a - b + c);

System.out.println("Result: " +expression);

When the expression is evaluated, the denominator becomes zero. Hence Java would throw
ArithmeticException when it’s executed. The exception logs would be:

Exception in thread "main" java.lang.ArithmeticException: / by zero

at TestClass.main(TestClass.java:8)
16. What is the difference between ClassNotFoundException and NoClassDefFoundError?

Both these exceptions occur when ClassLoader or JVM is not able to find classes while loading
during run-time. However, the difference between these 2 are:

ClassNotFoundException: This exception occurs when we try to load a class that is not found in the
classpath at runtime by making use of the loadClass() or Class.forName() methods.

NoClassDefFoundError: This exception occurs when a class was present at compile-time but was
not found at runtime.

17. What do you understand by an unreachable catch block error?

This error is thrown by the compiler when we have multiple catch blocks and keep parent classes
first and subclasses later. The catch blocks should follow the order of the most specific ones at the
top to the most general ones at the bottom. If this is not followed, an unreachable catch block
error is thrown during compile time.

Exception Handling Interview Questions for Experienced

1. Explain Java Exception Hierarchy.

Exceptions in Java are hierarchical and follow inheritance to categorize different kinds of
exceptions. The parent class of all exceptions and errors is Throwable. This class has 2 child classes
- Error and Exception.

Errors are those abnormal failures that are not in the scope of recovery for the application. It is not
possible to anticipate errors or recover from them. Errors could be due to failures in hardware,
out-of-memory, JVM crash, etc.

Exception is divided into 2 categories - Checked Exception and Unchecked Exception.

Checked Exceptions are those that can be anticipated in the program at the time of compilation
and we should try to handle this otherwise it leads to a compilation error. IllegalAccessException,
ClassNotFoundException, and FileNotFoundException are some of the types of checked exceptions.
Exception is the parent class of all checked exceptions.

Unchecked exceptions are those exceptions that occur during runtime and are not possible to
identify at the time of compilation. These exceptions are caused due to mistakes in application
programming - for example, we try to access an element from an array index that is out of bounds
from the length of the array, while trying to run operations on null objects and so on.
RuntimeException, ArrayIndexOutOfBoundException, NullPointerException, ClassCastException,
NumberFormatException, IllegalArgumentException, etc are some of the types of unchecked
exceptions. The parent class of all runtime/unchecked exceptions is RuntimeException.

The exception hierarchy in Java has been depicted in the image below:
2. What does JVM do when an exception occurs in a program?

When there is an exception inside a method, the method creates and passes (throws) the
Exception object to the JVM. This exception object has information regarding the type of exception
and the program state when this error happens. JVM is then responsible for finding if there are any
suitable exception handlers to handle this exception by going backwards in the call stack until it
finds the right handler. If a matching exception handler is not found anywhere in the call stack,
then the JVM terminates the program abruptly and displays the stack trace of the exception.

3. What happens when an exception is thrown by the main method?

When there is an exception thrown by the main() method if the exception is not handled, then the
program is terminated by the Java Runtime, and the exception message along with the stack trace
is printed in the system console.

4. Is it possible to throw checked exceptions from a static block?

We cannot throw a check exception from a static block. However, we can have try-catch logic that
handles the exception within the scope of that static block without rethrowing the exception using
the throw keyword. The exceptions cannot be propagated from static blocks because static blocks
are invoked at the compiled time only once and no method invokes these blocks.

5. What happens to the exception object after exception handling is complete?

The exception object will be garbage collected.

6. What are different scenarios where “Exception in thread main” types of error could occur?

The following are some of the scenarios causing an exception in the main thread:

Exception in thread main java.lang.UnsupportedClassVersionError: This occurs when the Java class
is compiled from one JDK version and we run the class in another JDK version.

Exception in thread main java.lang.NoSuchMethodError: main: This occurs when we try to run a
class that has no main method.
Exception in thread main java.lang.NoClassDefFoundError: This occurs if a ClassLoader is unable to
find that class in the classpath at the time of loading it.

Exception in thread “main” java.lang.ArithmeticException: This is an example exception. Here, in


the logic, ArithmeticException was thrown from the main method due to some erroneous logic in
the main or due to the methods called from the main that threw this exception but was not
handled there.

7. Under what circumstances should we subclass an Exception?

When there are exceptions that are to be thrown by the application, but the type is not
represented by any of the existing Exception types in Java, then we can provide more detailed
information by creating a custom exception. The creation of custom exceptions depends on the
business logic. While creating a custom exception, it is recommended to inherit from the most
specific Exception class that relates to the exception we want to throw. If there are no such classes
available, then we can choose the Exception class as the parent for this new custom exception.
Consider an example -
We want to access a file and return the first line of the file content.

try (Scanner file = new Scanner(new File(fileName))) {

if (file.hasNextLine()) return file.nextLine();

} catch(FileNotFoundException fnfeException) {

// Handle exception if the file is not found

In the above case, when there is an exception while reading the file - we do not know if it was
caused due to absence of the file or if the name of the file provided was wrong. To narrow this
down, we will create a custom exception called InvalidFileNameException by extending the
Exception class as shown below:

public class InvalidFileNameException extends Exception {

public InvalidFileNameException(String exceptionMessage) {

super(exceptionMessage);

To create a custom exception, we should also provide a constructor that makes a call to the parent
class constructor by using the super keyword. Our custom exception is ready. The code logic now
becomes:

try (Scanner file = new Scanner(new File(fileName))) {

if (file.hasNextLine()) return file.nextLine();

} catch(FileNotFoundException fnfeException) {

// check if the file name is valid or not

if (!ifFileNameValid(fileName)) {
throw new InvalidFileNameException("Filename : " + fileName + " is invalid");

// Handle exception if the filename was valid and if the file is not found

8. What happens when you run the below program?

import java.io.IOException;

import java.io.FileNotFoundException;

import javax.xml.bind.JAXBException;

public class TestExceptionDemo {

public static void main(String[] args) {

try {

demoException();

} catch (IOException e) {

System.out.println(e.getMessage());

} catch (FileNotFoundException e) {

System.out.println(e.getMessage());

} catch (JAXBException e) {

System.out.println(e.getMessage());

public static void demoException() throws IOException, FileNotFoundException,


JAXBException{

We know that the FileNotFoundException is the subclass of IOException - By the rule of multiple
catch block, we need to have the most specific exception at the top and the most generic
exception at the bottom. If there are no parent-child relationships between the exceptions, they
can be placed anywhere. In this example, JAXBException is not related to IOException and
FileNotFoundException exceptions. Hence, it can be placed anywhere in the multiple catch block
structure. However, IOException being the parent class is mentioned at the beginning and that is
followed by FileNotFoundException. This results in an error - Unreachable catch block for
FileNotFoundException. It is already handled by the catch block for IOException. To fix this issue,
depending on the business requirements, we can either remove the FileNotFoundException from
the throws list and catch block OR we can rearrange the catch blocks as shown below:

public static void main(String[] args) {

try {

demoException();

} catch (FileNotFoundException e) {

System.out.println(e.getMessage());

} catch (IOException e) {

System.out.println(e.getMessage());

} catch (JAXBException e) {

System.out.println(e.getMessage());

9. Does the finally block always get executed in the Java program?

The finally blocks are meant to be executed whenever there is an exception or not in the try-catch
blocks. However, there is one scenario where this block does not get executed. It is when we
use System.exit(0) in either try or catch block. This is because the System.exit(0) terminates the
running JVM.

10. Why it is always recommended to keep the clean-up activities like closing the I/O resources or
DB connections inside a finally block?

When there is no explicit logic to terminate the system by using System.exit(0), finally block is
always executed irrespective of whether the exception has occurred or not. By keeping these
cleanup operations in the finally block, it is always ensured that the operations are executed and
the resources are closed accordingly. However, to avoid exceptions in the finally block, we need to
add a proper validation check for the existence of the resource and then attempt to clean up the
resources accordingly.

11. Are we allowed to use only try blocks without a catch and finally blocks?

Before Java 7, we were not allowed to use only try blocks. The try block should have been followed
by a catch or a finally block. But from Java 7 onwards, we can simply have a try block with a catch
or finally blocks in the form of try-with-resources that takes parameters implementing
the AutoCloseable interface. Note that, if the parameters do not implement
the AutoCloseable interface, then it leads to an error.

12. What happens when the below program is run?


public class TestExceptionDemo {

public static void main(String[] args) {

try{

demoMethod();

}catch(NullPointerException e){

System.out.println(e.getMessage());

}catch(Exception e){

System.out.println(e.getMessage());

foobar();

public static void demoMethod(){

public static void foobar() throws NullPointerException{

The program compiles successfully and it runs and displays nothing as no logic in both methods
could result in an exception.

If there are any exceptions in the demoMethod(), we can always catch the exception and handle it.
If the method foobar() declares NullPointerException using throws clause, the method doesn’t
need to throw an exception. However, if there is a logic that results in performing operations on
null objects inside the foobar() method, then NullPointerException will be thrown by the method
to the main() method. Since there is no exception handling for this foobar() method, the program
will terminate displaying the error message and stack trace.

13. Is it possible to throw an Exception inside a Lambda Expression’s body?

Yes, it is possible. However, we need to note two points:


If we are using a standard functional interface that is given by Java, then we can throw only
unchecked exceptions. This is because the standard functional interfaces of Java do not have a
“throws” clause defined in their signature. For example, we can
throw IllegalArgumentException inside a function interface as shown below:

List<Integer> list = Arrays.asList(2,3,5,10,20);

list.forEach(i -> {

if (i < 0) {

throw new IllegalArgumentException("Negative numbers are not allowed.");

System.out.println(i);

});

If we are using custom functional interfaces, then we can throw checked as well as unchecked
exceptions. Custom functional interfaces can be defined by using
the @FunctionalInterface keyword.

14. What are the rules we should follow when overriding a method throwing an Exception?

The following are some of the rules that have to be followed while overriding method throwing
Exception:

Rule 1: If the parent class method is not throwing any exceptions, then the overridden child class
method should not throw checked exceptions. But it can throw an unchecked exception. Consider
an example that demonstrates this- We have 2 classes - ParentDemo and ChildDemo where the
latter is the subclass of the ParentDemo class. We have the doThis() the method that is overridden
in the ChildDemo class. The overridden method may only throw an unchecked exception. The
below example is valid since IllegalArgumentException is an unchecked exception.

class ParentDemo {

void doThis() {

// ...

class ChildDemo extends ParentDemo {

@Override

void doThis() throws IllegalArgumentException {

// ...

}
Rule 2: If the parent class method is throwing one or more checked exceptions, then the
overridden method in the child class can throw any unchecked exceptions or any exceptions that
are the same as checked exceptions of the parent method or the subclasses of those checked
exceptions. Consider the below example code:

class ParentDemo {

void doThis() throws IOException, ParseException {

// ...

void doThat() throws IOException {

// ...

class ChildDemo extends ParentDemo {

void doThis() throws IOException {

// ...

void doThat() throws FileNotFoundException, EOFException {

// ...

In this example, the doThis() method throws few exceptions than the parent method and
the doThat() method throws a greater number of exceptions, however, the scope of the exceptions
is not greater than the parent exceptions. If we try to throw a checked exception that was not
declared in the parent method or we throw an exception that has a broader scope, then it results
in a compilation error. For example, the below code is not valid as the parent method throws
a FileNotFoundException exception and the child method throws IOException which is broader in
scope as it is the parent class of FileNotFoundException:

class ParentDemo {

void doThis() throws FileNotFoundException {

// ...

}
}

class ChildDemo extends ParentDemo {

void doThis() throws IOException {

// Compilation error because IOException is of broader scope than FileNotFoundException

Rule 3: If the parent class method has a throws clause having unchecked exceptions, then the
overriding child method can throw any number of unchecked exceptions even if they are not
related to each other. Consider the below example. While the parent class doThis() method threw
only 1 unchecked exception which is IllegalArgumentException, the child class could throw
multiple unchecked exceptions as shown below:

class ParentDemo {

void doThis() throws IllegalArgumentException {

// ...

class ChildDemo extends ParentDemo {

void doThis() throws ArithmeticException, NumberFormatException, NullPointerException {

// ...

Exception Handling with Method Overriding in Java


There are many rules if we talk about method overriding with exception handling.
Some of the rules are listed below:
ADVERTISEMENT
ADVERTISEMENT
If the superclass method does not declare an exception
If the superclass method does not declare an exception, subclass overridden method cannot
declare the checked exception but it can declare unchecked exception.
If the superclass method declares an exception
If the superclass method declares an exception, subclass overridden method can declare
same, subclass exception or no exception but cannot declare parent exception.
If the superclass method does not declare an exception
Rule 1: If the superclass method does not declare an exception, subclass overridden method
cannot declare the checked exception.
Let's consider following example based on the above rule.
TestExceptionChild.java
import java.io.*;
class Parent{

// defining the method


void msg() {
System.out.println("parent method");
}
}

public class TestExceptionChild extends Parent{

// overriding the method in child class


// gives compile time error
void msg() throws IOException {
System.out.println("TestExceptionChild");
}

public static void main(String args[]) {


Parent p = new TestExceptionChild();
p.msg();
}
}
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.
TestExceptionChild1.java
import java.io.*;
class Parent{
void msg() {
System.out.println("parent method");
}
}

class TestExceptionChild1 extends Parent{


void msg()throws ArithmeticException {
System.out.println("child method");
}

public static void main(String args[]) {


Parent p = new TestExceptionChild1();
p.msg();
}
}
Output:

If the superclass method declares an exception


Rule 1: If the superclass method declares an exception, subclass overridden method can
declare the same subclass exception or no exception but cannot declare parent exception.
Example in case subclass overridden method declares parent exception
TestExceptionChild2.java
import java.io.*;
class Parent{
void msg()throws ArithmeticException {
System.out.println("parent method");
}
}

public class TestExceptionChild2 extends Parent{


void msg()throws Exception {
System.out.println("child method");
}

public static void main(String args[]) {


Parent p = new TestExceptionChild2();

try {
p.msg();
}
catch (Exception e){}

}
}
Output:

Example in case subclass overridden method declares same exception


TestExceptionChild3.java
import java.io.*;
class Parent{
void msg() throws Exception {
System.out.println("parent method");
}
}

public class TestExceptionChild3 extends Parent {


void msg()throws Exception {
System.out.println("child method");
}

public static void main(String args[]){


Parent p = new TestExceptionChild3();

try {
p.msg();
}
catch(Exception e) {}
}
}
Output:

Example in case subclass overridden method declares subclass exception


TestExceptionChild4.java
import java.io.*;
class Parent{
void msg()throws Exception {
System.out.println("parent method");
}
}

class TestExceptionChild4 extends Parent{


void msg()throws ArithmeticException {
System.out.println("child method");
}

public static void main(String args[]){


Parent p = new TestExceptionChild4();

try {
p.msg();
}
catch(Exception e) {}
}
}
Output:
Example in case subclass overridden method declares no exception
TestExceptionChild5.java
import java.io.*;
class Parent {
void msg()throws Exception{
System.out.println("parent method");
}
}

class TestExceptionChild5 extends Parent{


void msg() {
System.out.println("child method");
}

public static void main(String args[]){


Parent p = new TestExceptionChild5();

try {
p.msg();
}
catch(Exception e) {}

}
}
Output:

Thread Questions

What do you mean by Multithreading? Why is it important?


Multithreading means multiple threads and is considered one of the most important features of
Java. As the name suggests, it is the ability of a CPU to execute multiple threads independently at
the same time but share the process resources simultaneously. Its main purpose is to provide
simultaneous execution of multiple threads to utilize the CPU time as much as possible. It is a Java
feature where one can subdivide the specific program into two or more threads to make the
execution of the program fast and easy.
Multithreading Interview Questions in Java for Freshers
1. What are the benefits of using Multithreading?
There are various benefits of multithreading as given below:
Allow the program to run continuously even if a part of it is blocked.
Improve performance as compared to traditional parallel programs that use multiple processes.
Allows to write effective programs that utilize maximum CPU time
Improves the responsiveness of complex applications or programs.
Increase use of CPU resources and reduce costs of maintenance.
Saves time and parallelism tasks.
If an exception occurs in a single thread, it will not affect other threads as threads are
independent.
Less resource-intensive than executing multiple processes at the same time.

2. What is Thread in Java?


Threads are basically the lightweight and smallest unit of processing that can be managed
independently by a scheduler. Threads are referred to as parts of a process that simply let a
program execute efficiently with other parts or threads of the process at the same time. Using
threads, one can perform complicated tasks in the easiest way. It is considered the simplest way to
take advantage of multiple CPUs available in a machine. They share the common address space
and are independent of each other.
3. What are the two ways of implementing thread in Java?
There are basically two ways of implementing thread in java as given below:
Extending the Thread class
Example:
class MultithreadingDemo extends Thread
{
public void run()
{
System.out.println("My thread is in running state.");
}
public static void main(String args[])
{
MultithreadingDemo obj=new MultithreadingDemo();
obj.start();
}
}
Output:
My thread is in running state.
Implementing Runnable interface in Java
Example:
class MultithreadingDemo implements Runnable
{
public void run()
{
System.out.println("My thread is in running state.");
}
public static void main(String args[])
{
MultithreadingDemo obj=new MultithreadingDemo();
Threadtobj =new Thread(obj); tobj.start();
}
}
Output:
My thread is in running state.

4. What's the difference between thread and process?


Thread: It simply refers to the smallest units of the particular process. It has the ability to execute
different parts (referred to as thread) of the program at the same time.

Process: It simply refers to a program that is in execution i.e., an active program. A process can be
handled using PCB (Process Control Block).
Thread Process
It is a program in execution containing multiple
It is a subset of a subunit of a process.
threads.
In this, inter-thread communication is faster, less
In this, inter-process communication is slower,
expensive, easy and efficient because threads share
expensive, and complex because each process
the same memory address of the process they
has different memory space or address.,
belong to.
These are easier to create, lightweight, and have less These are difficult to create, heavyweight, and
overhead. have more overhead.
It requires less time for creation, termination, and It requires more time for creation,
context switching. termination, and context switching.
Processes without threads use more
Processes with multiple threads use fewer resources.
resources.
Threads are parts of a process, so they are
dependent on each other but each thread executes Processes are independent of each other.
independently.
There is a need for synchronization in threads to There is no need for synchronization in each
avoid unexpected scenarios or problems. process.
They share data and information with each other. They do not share data with each other.
5. What’s the difference between class lock and object lock?
Class Lock: In java, each and every class has a unique lock usually referred to as a class level lock.
These locks are achieved using the keyword ‘static synchronized’ and can be used to make static
data thread-safe. It is generally used when one wants to prevent multiple threads from entering a
synchronized block.

Example:
public class ClassLevelLockExample
{
public void classLevelLockMethod()
{
synchronized (ClassLevelLockExample.class)
{
//DO your stuff here
}
}
}
Object Lock: In java, each and every object has a unique lock usually referred to as an object-level
lock. These locks are achieved using the keyword ‘synchronized’ and can be used to protect non-
static data. It is generally used when one wants to synchronize a non-static method or block so that
only the thread will be able to execute the code block on a given instance of the class.

Example:
public class ObjectLevelLockExample
{
public void objectLevelLockMethod()
{
synchronized (this)
{
//DO your stuff here
}
}
}
6. What's the difference between User thread and Daemon thread?
User and Daemon are basically two types of thread used in Java by using a ‘Thread Class’.

User Thread (Non-Daemon Thread): In Java, user threads have a specific life cycle and its life is
independent of any other thread. JVM (Java Virtual Machine) waits for any of the user threads to
complete its tasks before terminating it. When user threads are finished, JVM terminates the
whole program along with associated daemon threads.

Daemon Thread: In Java, daemon threads are basically referred to as a service provider that
provides services and support to user threads. There are basically two methods available in thread
class for daemon thread: setDaemon() and isDaemon().

User Thread vs Daemon Thread


User Thread Daemon Thread
JVM waits for user threads to finish JVM does not wait for daemon threads to finish their tasks
their tasks before termination. before termination.
These threads are normally created by
the user for executing tasks These threads are normally created by JVM.
concurrently.
They are used for critical tasks or core They are not used for any critical tasks but to do some
work of an application. supporting tasks.
These threads are referred to as low priority threads,
These threads are referred to as high-
therefore are especially required for supporting background
priority tasks, therefore are required
tasks like garbage collection, releasing memory of unused
for running in the foreground.
objects, etc.
7. How can we create daemon threads?
We can create daemon threads in java using the thread class setDaemon(true). It is used to mark
the current thread as daemon thread or user thread. isDaemon() method is generally used to
check whether the current thread is daemon or not. If the thread is a daemon, it will return true
otherwise it returns false.
Example:
Program to illustrate the use of setDaemon() and isDaemon() method.
public class DaemonThread extends Thread
{
public DaemonThread(String name){
super(name);
}
public void run()
{
// Checking whether the thread is Daemon or not
if(Thread.currentThread().isDaemon())
{
System.out.println(getName() + " is Daemon thread");
}
else
{
System.out.println(getName() + " is User thread");
}
}
public static void main(String[] args)
{
DaemonThread t1 = new DaemonThread("t1");
DaemonThread t2 = new DaemonThread("t2");
DaemonThread t3 = new DaemonThread("t3");
// Setting user thread t1 to Daemon
t1.setDaemon(true);
// starting first 2 threads
t1.start();
t2.start();
// Setting user thread t3 to Daemon
t3.setDaemon(true);
t3.start();
}
}
Output:
t1 is Daemon thread
t3 is Daemon thread
t2 is User thread
But one can only call the setDaemon() method before start() method otherwise it will definitely
throw IllegalThreadStateException as shown below:
public class DaemonThread extends Thread
{
public void run()
{
System.out.println("Thread name: " + Thread.currentThread().getName());
System.out.println("Check if its DaemonThread: "
+ Thread.currentThread().isDaemon());
}
public static void main(String[] args)
{
DaemonThread t1 = new DaemonThread();
DaemonThread t2 = new DaemonThread();
t1.start();
// Exception as the thread is already started
t1.setDaemon(true);
t2.start();
}
}
Output:
Thread name: Thread-0
Check if its DaemonThread: false

8. What are the wait() and sleep() methods?


wait(): As the name suggests, it is a non-static method that causes the current thread to wait and
go to sleep until some other threads call the notify () or notifyAll() method for the object’s monitor
(lock). It simply releases the lock and is mostly used for inter-thread communication. It is defined
in the object class, and should only be called from a synchronized context.
Example:
synchronized(monitor)
{
monitor.wait(); Here Lock Is Released by Current Thread
}
sleep(): As the name suggests, it is a static method that pauses or stops the execution of the
current thread for some specified period. It doesn’t release the lock while waiting and is mostly
used to introduce pause on execution. It is defined in thread class, and no need to call from a
synchronized context.
Example:
synchronized(monitor)
{
Thread.sleep(1000); Here Lock Is Held by The Current Thread
//after 1000 milliseconds, the current thread will wake up, or after we call that is interrupt()
method
}
9. What’s the difference between notify() and notifyAll()?
notify(): It sends a notification and wakes up only a single thread instead of multiple threads that
are waiting on the object’s monitor.

notifyAll(): It sends notifications and wakes up all threads and allows them to compete for the
object's monitor instead of a single thread.

10. Why wait(), notify(), and notifyAll() methods are present in Object class?
We know that every object has a monitor that allows the thread to hold a lock on the object. But
the thread class doesn't contain any monitors. Thread usually waits for the object’s monitor (lock)
by calling the wait() method on an object, and notify other threads that are waiting for the same
lock using notify() or notifyAll() method. Therefore, these three methods are called on objects
only and allow all threads to communicate with each that are created on that object.
11. What is Runnable and Callable Interface? Write the difference between them.
Both the interfaces are generally used to encapsulate tasks that are needed to be executed by
another thread. But there are some differences between them as given below:

Running Interface: This interface is basically available in Java right from the beginning. It is simply
used to execute code on a concurrent thread.
Callable Interface: This interface is basically a new one that was introduced as a part of the
concurrency package. It addresses the limitation of runnable interfaces along with some major
changes like generics, enum, static imports, variable argument method, etc. It uses generics to
define the return type of object.
public interface Runnable
{
public abstract void run();
}
public interface Callable<V>
{
V call() throws Exception;
}
Runnable Interface vs Callable Interface
Runnable Interface Callable Interface
It does not return any result and therefore, cannot It returns a result and therefore, can throw an
throw a checked exception. exception.
It cannot be passed to invokeAll method. It can be passed to invokeAll method.
It was introduced in JDK 5.0, so one cannot
It was introduced in JDK 1.0.
use it before Java 5.
It simply belongs to Java.lang. It simply belongs to java.util.concurrent.
It uses the run() method to define a task. It uses the call() method to define a task.
To use this interface, one needs to override the run() To use this interface, one needs to override
method. the call() method.
12. What is the start() and run() method of Thread class?
start(): In simple words, the start() method is used to start or begin the execution of a newly
created thread. When the start() method is called, a new thread is created and this newly created
thread executes the task that is kept in the run() method. One can call the start() method only
once.

run(): In simple words, the run() method is used to start or begin the execution of the same
thread. When the run() method is called, no new thread is created as in the case of the start()
method. This method is executed by the current thread. One can call the run() method multiple
times.

13. Explain thread pool?


A Thread pool is simply a collection of pre-initialized or worker threads at the start-up that can be
used to execute tasks and put back in the pool when completed. It is referred to as pool threads in
which a group of fixed-size threads is created. By reducing the number of application threads and
managing their lifecycle, one can mitigate the issue of performance using a thread pool. Using
threads, performance can be enhanced and better system stability can occur. To create the thread
pools, java.util.concurrent.Executors class usually provides factory methods.
14. What’s the purpose of the join() method?
join() method is generally used to pause the execution of a current thread unless and until the
specified thread on which join is called is dead or completed. To stop a thread from running until
another thread gets ended, this method can be used. It joins the start of a thread execution to the
end of another thread’s execution. It is considered the final method of a thread class.
15. What do you mean by garbage collection?
Garbage collection is basically a process of managing memory automatically. It uses several GC
algorithms among which the popular one includes Mark and Sweep. The process includes three
phases i.e., marking, deletion, and compaction/copying. In simple words, a garbage collector finds
objects that are no longer required by the program and then delete or remove these unused
objects to free up the memory space.
16. Explain the meaning of the deadlock and when it can occur?
Deadlock, as the name suggests, is a situation where multiple threads are blocked forever. It
generally occurs when multiple threads hold locks on different resources and are waiting for other
resources to complete their task.

The above diagram shows a deadlock situation where two threads are blocked forever. Thread 1 is
holding Object 1 but needs object 2 to complete processing whereas Thread 2 is holding Object 2
but needs object 1 first. In such conditions, both of them will hold lock forever and will never
complete tasks.
17. Explain volatile variables in Java?
A volatile variable is basically a keyword that is used to ensure and address the visibility of changes
to variables in multithreaded programming. This keyword cannot be used with classes and
methods, instead can be used with variables. It is simply used to achieve thread-safety. If you mark
any variable as volatile, then all the threads can read its value directly from the main memory
rather than CPU cache, so that each thread can get an updated value of the variable.
18. How do threads communicate with each other?
Threads can communicate using three methods i.e., wait(), notify(), and notifyAll().
19. Can two threads execute two methods (static and non-static concurrently)?
Yes, it is possible. If both the threads acquire locks on different objects, then they can execute
concurrently without any problem.
20. What is the purpose of the finalize() method?
Finalize() method is basically a method of Object class specially used to perform cleanup
operations on unmanaged resources just before garbage collection. It is not at all intended to be
called a normal method. After the complete execution of finalize() method, the object gets
destroyed automatically.

Multithreading Interview Questions in Java for Experienced

1. What is the synchronization process? Why use it?


Synchronization is basically a process in java that enables a simple strategy for avoiding thread
interference and memory consistency errors. This process makes sure that resource will be only
used one thread at a time when one thread tries to access a shared resource. It can be achieved in
three different ways as given below:
By the synchronized method
By synchronized block
By static synchronization
Syntax:
synchronized (object)
{
//statement to be synchronized
}
2. What is synchronized method and synchronized block? Which one should be preferred?
Synchronized Method: In this method, the thread acquires a lock on the object when they enter
the synchronized method and releases the lock either normally or by throwing an exception when
they leave the method. No other thread can use the whole method unless and until the current
thread finishes its execution and release the lock. It can be used when one wants to lock on the
entire functionality of a particular method.

Synchronized Block: In this method, the thread acquires a lock on the object between parentheses
after the synchronized keyword, and releases the lock when they leave the block. No other thread
can acquire a lock on the locked object unless and until the synchronized block exists. It can be
used when one wants to keep other parts of the programs accessible to other threads.

Synchronized blocks should be preferred more as it boosts the performance of a particular


program. It only locks a certain part of the program (critical section) rather than the entire method
and therefore leads to less contention.
3. What is thread starvation?
Thread starvation is basically a situation or condition where a thread won’t be able to have regular
access to shared resources and therefore is unable to proceed or make progress. This is because
other threads have high priority and occupy the resources for too long. This usually happens with
low-priority threads that do not get CPU for its execution to carry on.

4. What is Livelock? What happens when it occurs?


Similar to deadlock, livelock is also another concurrency problem. In this case, the state of threads
changes between one another without making any progress. Threads are not blocked but their
execution is stopped due to the unavailability of resources.
5. What is BlockingQueue?
BlockingQueue basically represents a queue that is thread-safe. Producer thread inserts
resource/element into the queue using put() method unless it gets full and consumer thread takes
resources from the queue using take() method until it gets empty. But if a thread tries to dequeue
from an empty queue, then a particular thread will be blocked until some other thread inserts an
item into the queue, or if a thread tries to insert an item into a queue that is already full, then a
particular thread will be blocked until some threads take away an item from the queue.

Example:
package org.arpit.java2blog;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class BlockingQueuePCExample {

public static void main(String[] args) {

BlockingQueue<String> queue=new ArrayBlockingQueue<>(5);


Producer producer=new Producer(queue);
Consumer consumer=new Consumer(queue);
Thread producerThread = new Thread(producer);
Thread consumerThread = new Thread(consumer);

producerThread.start();
consumerThread.start();

static class Producer implements Runnable {

BlockingQueue<String> queue=null;
public Producer(BlockingQueue queue) {
super();
this.queue = queue;
}

@Override
public void run() {

try {
System.out.println("Producing element 1");
queue.put("Element 1");
Thread.sleep(1000);
System.out.println("Producing element 2");
queue.put("Element 2");
Thread.sleep(1000);
System.out.println("Producing element 3");
queue.put("Element 3");
} catch (InterruptedException e) {

e.printStackTrace();
}
}
}

static class Consumer implements Runnable {

BlockingQueue<String> queue=null;

public Consumer(BlockingQueue queue) {


super();
this.queue = queue;
}

@Override
public void run() {

while(true)
{
try {
System.out.println("Consumed "+queue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}
}
Output:
Producing element 1
Consumed Element 1
Producing element 2
Consumed Element 2
Producing element 3
Consumed Element 3
6. Can you start a thread twice?
No, it's not at all possible to restart a thread once a thread gets started and completes its
execution. Thread only runs once and if you try to run it for a second time, then it will throw a
runtime exception i.e., java.lang.IllegalThreadStateException.

Example:
public class TestThreadTwice1 extends Thread{
public void run(){
System.out.println(" thread is executing now........");
}
public static void main(String args[]){
TestThreadTwice1 t1=new TestThreadTwice1();
t1.start();
t1.start();
}
}
Output:
thread is executing now........
Exception in thread "main" java.lang.IllegalThreadStateException
7. Explain context switching.
Context switching is basically an important feature of multithreading. It is referred to as switching
of CPU from one thread or process to another one. It allows multiple processes to share the same
CPU. In context switching, the state of thread or process is stored so that the execution of the
thread can be resumed later if required.
8. What is CyclicBarrier and CountDownLatch?
CyclicBarrier and CountDownLatch, both are required for managing multithreaded programming.
But there is some difference between them as given below:
CyclicBarrier: It is a tool to synchronize threads processing using some algorithm. It enables a set of
threads to wait for each other till they reach a common execution point or common barrier points,
and then let them further continue execution. One can reuse the same CyclicBarrier even if the
barrier is broken by setting it.
CountDownLatch: It is a tool that enables main threads to wait until mandatory operations are
performed and completed by other threads. In simple words, it makes sure that a thread waits
until the execution in another thread completes before it starts its execution. One cannot reuse
the same CountDownLatch once the count reaches 0.
9. What do you mean by inter-thread communication?
Inter-thread communication, as the name suggests, is a process or mechanism using which
multiple threads can communicate with each other. It is especially used to avoid thread polling in
java and can be obtained using wait(), notify(), and notifyAll() methods.
10. What is Thread Scheduler and Time Slicing?
Thread Scheduler: It is a component of JVM that is used to decide which thread will execute next if
multiple threads are waiting to get the chance of execution. By looking at the priority assigned to
each thread that is READY, the thread scheduler selects the next run to execute. To schedule the
threads, it mainly uses two mechanisms: Preemptive Scheduling and Time slicing scheduling.

Time Slicing: It is especially used to divide CPU time and allocate them to active threads. In this,
each thread will get a predefined slice of time to execute. When the time expires, a particular
thread has to wait till other threads get their chances to use their time in a round-robin fashion.
Every running thread will get executed for a fixed time period.
11. What is a shutdown hook?
A shutdown hook is simply a thread that is invoked implicitly before JVM shuts down. It is one of
the most important features of JVM because it provides the capacity to do resource cleanup or
save application state JVM shuts down. By calling the halt(int) method of the Runtime class, the
shutdown hook can be stopped. Using the following method, one can add a shutdown hook.
public void addShutdownHook(Thread hook){}
Runtime r=Runtime.getRuntime();
r.addShutdownHook(new MyThread());
12. What is busy spinning?
Busy Spinning, also known as Busy-waiting, is a technique in which one thread waits for some
condition to happen, without calling wait or sleep methods and releasing the CPU. In this
condition, one can pause a thread by making it run an empty loop for a certain time period, and it
does not even give CPY control. Therefore, it is used to preserve CPU caches and avoid the cost of
rebuilding cache.
13. What is ConcurrentHashMap and Hashtable? In java, why is ConcurrentHashMap considered
faster than Hashtable?
ConcurrentHashMap: It was introduced in Java 1.5 to store data using multiple buckets. As the
name suggests, it allows concurrent read and writes operations to the map. It only locks a certain
portion of the map while doing iteration to provide thread safety so that other readers can still
have access to the map without waiting for iteration to complete.
Hashtable: It is a thread-safe legacy class that was introduced in old versions of java to store key or
value pairs using a hash table. It does not provide any lock-free read, unlike ConcurrentHashMap.
It just locks the entire map while doing iteration.

ConcurrentHashMap and Hashtable, both are thread-safe but ConcurrentHashMap generally


avoids read locks and improves performance, unlike Hashtable. ConcurrentHashMap also provides
lock-free reads, unlike Hashtable. Therefore, ConcurrentHashMap is considered faster than
Hashtable especially when the number of readers is more as compared to the number of writers.
14. Explain thread priority.
Thread priority simply means that threads with the highest priority will get a chance for execution
prior to low-priority threads. One can specify the priority but it's not necessary that the highest
priority thread will get executed before the lower-priority thread. Thread scheduler assigns
processor to thread on the basis of thread priority. The range of priority changes between 1-10
from lowest priority to highest priority.

15. What do you mean by the ThreadLocal variable in Java?


ThreadLocal variables are special kinds of variables created and provided by the Java ThreadLocal
class. These variables are only allowed to be read and written by the same thread. Two threads
cannot be able to see each other’s ThreadLocal variable, so even if they will execute the same
code, then there won't be any race condition and the code will be thread-safe.

Example:
public class ThreadLocalExp
{
public static class MyRunnable implements Runnable
{
private ThreadLocal<Integer> threadLocal =
new ThreadLocal<Integer>();
@Override
public void run() {
threadLocal.set( (int) (Math.random() * 50D) );
try
{
Thread.sleep(1000);
} catch (InterruptedException e) {
}
System.out.println(threadLocal.get());
}
}
public static void main(String[] args)
{
MyRunnable runnableInstance = new MyRunnable();
Thread t1 = new Thread(runnableInstance);
Thread t2 = new Thread(runnableInstance);
// this will call run() method
t1.start();
t2.start();
}
}
Output:
10
33
10 33
16. What is semaphore?
Semaphore is regarded as a thread synchronization construct that is usually required to control
and manage the access to the shared resource using counters. It simply sets the limit of the
thread. The semaphore class is defined within the package java.util.concurrent and can be used to
send signals between threads to avoid missed signals or to guard critical sections. It can also be
used to implement resource pools or bounded collection.
17. Explain Thread Group. Why should we not use it?
ThreadGroup is a class that is used to create multiple groups of threads in a single object. This
group of threads is present in the form of three structures in which every thread group has a
parent except the initial thread. Thread groups can contain other thread groups also. A thread is
only allowed to have access to information about its own thread group, not other thread groups.

Previously in the old version of Java, the only functionality that did not work without a thread
group was uncaughtException( Thread t, Throwable e). But now in Java 5 versions, there is
Thread.setUncaughtExceptionHandler(UncaughtExceptionHandler). So now even that works
without thread groups and therefore, there is no need to use thread groups.
t1.setUncaughtExceptionHandler(new UncaughtExceptionHandler()
{
@Override
public void uncaughtException(Thread t, Throwable e)
{
System.out.println("exception occured:"+e.getMessage());
}
};
18. What is the ExecutorService interface?
ExecutorService interface is basically a sub-interface of Executor interface with some additional
methods or features that help in managing and controlling the execution of threads. It enables us
to execute tasks asynchronously on threads.
Example:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class TestThread {


public static void main(final String[] arguments) throws InterruptedException {
ExecutorService e = Executors.newSingleThreadExecutor();

try {
e.submit(new Thread());
System.out.println("Shutdown executor");
e.shutdown();
e.awaitTermination(5, TimeUnit.SECONDS);
} catch (InterruptedException ex) {
System.err.println("tasks interrupted");
} finally {

if (!e.isTerminated()) {
System.err.println("cancel non-finished tasks");
}
e.shutdownNow();
System.out.println("shutdown finished");
}
}

static class Task implements Runnable {

public void run() {

try {
Long duration = (long) (Math.random() * 20);
System.out.println("Running Task!");
TimeUnit.SECONDS.sleep(duration);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
}
Output:
Shutdown executor
shutdown finished
19. What will happen if we don’t override the thread class run() method?
Nothing will happen as such if we don’t override the run() method. The compiler will not show any
error. It will execute the run() method of thread class and we will just don’t get any output because
the run() method is with an empty implementation.

Example:
class MyThread extends Thread {
//don't override run() method
}
public class DontOverrideRun {
public static void main(String[] args) {
System.out.println("Started Main.");
MyThread thread1=new MyThread();
thread1.start();
System.out.println("Ended Main.");
}
}
Output:
Started Main.
Ended Main.
20. What is the lock interface? Why is it better to use a lock interface rather than a synchronized
block.?
Lock interface was introduced in Java 1.5 and is generally used as a synchronization mechanism to
provide important operations for blocking.

Advantages of using Lock interface over Synchronization block:


Methods of Lock interface i.e., Lock() and Unlock() can be called in different methods. It is the
main advantage of a lock interface over a synchronized block because the synchronized block is
fully contained in a single method.
Lock interface is more flexible and makes sure that the longest waiting thread gets a fair chance for
execution, unlike the synchronization block.
21. Is it possible to call the run() method directly to start a new thread?
No, it's not possible at all. You need to call the start method to create a new thread otherwise run
method won't create a new thread. Instead, it will execute in the current thread.
22. Is it possible that each thread can have its stack in multithreaded programming?
Of course, it is possible. In multithreaded programming, each thread maintains its own separate
stack area in memory because of which every thread is independent of each other rather than
dependent.

You might also like