Java Basic Interview Questions: 1. Why Is Java A Platform Independent Language?
Java Basic Interview Questions: 1. Why Is Java A Platform Independent Language?
Go through all the questions to enhance your chances of performing well in the
interviews. The questions will revolve around the basic and core fundamentals of
Java.
So, let’s dive deep into the plethora of useful interview questions on Java.
Java language was developed in such a way that it does not depend on any hardware
or software due to the fact that the compiler compiles the code and then converts it
to platform-independent byte code which can be run on multiple systems.
The only condition to run that byte code is for the machine to have a runtime
environment (JRE) installed in it.
Java supports primitive data types - byte, boolean, char, short, int, float, long, and
double and hence it is not a pure object-oriented language.
3. Pointers are used in C/ C++. Why does Java not make use of
pointers?
Pointers are quite complicated and unsafe to use by beginner programmers. Java
focuses on code simplicity, and the usage of pointers can make it challenging.
Pointer utilization can also cause potential errors. Moreover, security is also
compromised if pointers are used because the users can directly access memory with
the help of pointers.
All the objects of the class will have their copy of the variables for utilization. If any
modification is done on these variables, then only that instance will be impacted by
it, and all other class instances continue to remain unaffected.
Example:
class Athlete {
public String athleteName;
public double athleteSpeed;
public int athleteAge;
}
Local variables are those variables present within a block, function, or constructor
and can be accessed only inside them. The utilization of the variable is restricted to
the block scope. Whenever a local variable is declared inside a method, the other
class methods don’t have any knowledge about the local variable.
Example:
JIT stands for Just-In-Time and it is used for improving the performance during run
time. It does the task of compiling parts of byte code having similar functionality at
the same time thereby reducing the amount of compilation time for the code to run.
The compiler is nothing but a translator of source code to machine-executable code.
But what is special about the JIT compiler? Let us see how it works:
o First, the Java source code (.java) conversion to byte code (.class) occurs with the help
of the javac compiler.
o Then, the .class files are loaded at run time by JVM and with the help of an
interpreter, these are converted to machine understandable code.
o JIT compiler is a part of JVM. When the JIT compiler is enabled, the JVM analyzes the
method calls in the .class files and compiles them to get more efficient and native
code. It also ensures that the prioritized method calls are optimized.
o Once the above step is done, the JVM executes the optimized code directly instead
of interpreting the code again. This increases the performance and speed of the
execution.
7. Can you tell the difference between equals() method and equality
operator (==) in Java?
equals() ==
This is a method defined in the Object
class. It is a binary operator in Java.
This method is used for checking the This operator is used for comparing
equality of contents between two addresses (or references), i.e checks if both
objects as per the specified business the objects are pointing to the same memory
logic. location.
Note:
In the cases where the equals method is not overridden in a class, then the class uses
the default implementation of the equals method that is closest to the parent class.
Object class is considered as the parent class of all the java classes. The
implementation of the equals method in the Object class uses the == operator to
compare two objects. This default implementation can be overridden as per the
business logic.
Infinite loops are those loops that run infinitely without any breaking conditions.
Some examples of consciously declaring infinite loop is:
class Hospital {
int variable1, variable2;
double variable3;
public Hospital(int doctors, int nurses) {
variable1 = doctors;
variable2 = nurses;
}
public Hospital(int doctors) {
variable1 = doctors;
}
public Hospital(double salaries) {
variable3 = salaries
}
}
Three constructors are defined here but they differ on the basis of parameter type
and their numbers.
The only difference in the return type of the method does not promote method
overloading. The following example will furnish you with a clear picture of it.
class OverloadingHelp {
public int findarea (int l, int b) {
int var1;
var1 = l * b;
return var1;
}
public int findarea (int l, int b, int h) {
int var2;
var2 = l * b * h;
return var2;
}
}
Both the functions have the same name but differ in the number of arguments. The
first method calculates the area of the rectangle, whereas the second method
calculates the area of a cuboid.
Method overriding is the concept in which two methods having the same method
signature are present in two different classes in which an inheritance relationship is
present. A particular method implementation (already present in the base class) is
possible for the derived class by using method overriding.
Let’s give a look at this example:
class HumanBeing {
public int walk (int distance, int time) {
int speed = distance / time;
return speed;
}
}
class Athlete extends HumanBeing {
public int walk(int distance, int time) {
int speed = distance / time;
speed = speed * 2;
return speed;
}
}
Both class methods have the name walk and the same parameters, distance, and
time. If the derived class method is called, then the base class method walk gets
overridden by that of the derived class.
11. A single try block and multiple catch blocks can co-exist in a Java
Program. Explain.
Yes, multiple catch blocks can exist but specific approaches should come prior to the
general approach because only the first catch block satisfying the catch condition is
executed. The given code illustrates the same:
Here, the second catch block will be executed because of division by 0 (i / x). In case
x was greater than 0 then the first catch block will execute because for loop runs till i
= n and array index are till n-1.
12. Explain the use of final keyword in variable, method and class.
In Java, the final keyword is used as defining something as constant /final and
represents the non-access modifier.
final variable:
o When a variable is declared as final in Java, the value can’t be modified once it has
been assigned.
o If any value has not been assigned to that variable, then it can be assigned only by
the constructor of the class.
final method:
o A method declared as final cannot be overridden by its children's classes.
o A constructor cannot be marked as final because whenever a class is inherited, the
constructors are not inherited. Hence, marking it final doesn't make sense. Java
throws compilation error saying - modifier final not allowed here
final class:
o No classes can be inherited from the class declared as final. But that final class can
extend other classes for its usage.
13. Do final, finally and finalize keywords have the same function?
Final: If any restriction is required for classes, variables, or methods, the final
keyword comes in handy. Inheritance of a final class and overriding of a final method
is restricted by the use of the final keyword. The variable value becomes fixed after
incorporating the final keyword. Example:
Finally: It is the block present in a program where all the codes written inside it get
executed irrespective of handling of exceptions. Example:
try {
int variable = 5;
}
catch (Exception exception) {
System.out.println("Exception occurred");
}
finally {
System.out.println("Execution of finally block");
}
Finalize: Prior to the garbage collection of an object, the finalize method is called so
that the clean-up activity is implemented. Example:
The super keyword is used to access hidden fields and overridden methods or
attributes of the parent class.
Following are the cases when this keyword can be used:
o Accessing data members of parent class when the member names of the class and its
child subclasses are same.
o To call the default and parameterized constructor of the parent class inside the child
class.
o Accessing the parent class methods when the child classes have overridden them.
The following example demonstrates all 3 cases when a super keyword is used.
public class Parent{
private int num = 1;
Parent(){
System.out.println("Parent class default constructor.");
}
Parent(String x){
System.out.println("Parent class parameterised constructor.");
}
Child(){
System.out.println("Child class default Constructor");
void printNum(){
System.out.println(num);
System.out.println(super.num); //prints the value of num of pare
nt class
}
@Override
public void foo(){
System.out.println("Parent class foo!");
super.foo(); //Calls foo method of Parent class inside the Ov
erriden foo method of Child class.
}
}
Yes! There can be two or more static methods in a class with the same name but
differing input parameters.
No! Declaration of static methods having the same signature can be done in the
subclass but run time polymorphism can not take place in such cases.
Overriding or dynamic polymorphism occurs during the runtime, but the static
methods are loaded and looked up at the compile time statically. Hence, these
methods cant be overridden.
The main objective of this process is to free up the memory space occupied by the
unnecessary and unreachable objects during the Java program execution by deleting
those unreachable objects.
This ensures that the memory resource is used efficiently, but it provides no
guarantee that there would be sufficient memory for the program execution.
Heap.
Java Intermediate Interview Questions
19. Apart from the security aspect, what are the reasons behind
making strings immutable in Java?
String Pool: Designers of Java were aware of the fact that String data type is going
to be majorly used by the programmers and developers. Thus, they wanted
optimization from the beginning. They came up with the notion of using the String
pool (a storage area in Java heap) to store the String literals. They intended to
decrease the temporary String object with the help of sharing. An immutable class is
needed to facilitate sharing. The sharing of the mutable structures between two
unknown parties is not possible. Thus, immutable Java String helps in executing the
concept of String Pool.
Storage area: In string, the String pool serves as the storage area. For StringBuilder
and StringBuffer, heap memory is the storage area.
Mutability: A String is immutable, whereas both the StringBuilder and StringBuffer
are mutable.
Efficiency: It is quite slow to work with a String. However, StringBuilder is the fastest
in performing operations. The speed of a StringBuffer is more than a String and less
than a StringBuilder. (For example appending a character is fastest in StringBuilder
and very slow in String because a new memory is required for the new String with
appended character.)
Thread-safe: In the case of a threaded environment, StringBuilder and StringBuffer
are used whereas a String is not used. However, StringBuilder is suitable for an
environment with a single thread, and a StringBuffer is suitable for multiple threads.
Syntax:
// String
String first = "InterviewBit";
String second = new String("InterviewBit");
// StringBuffer
StringBuffer third = new StringBuffer("InterviewBit");
// StringBuilder
StringBuilder fourth = new StringBuilder("InterviewBit");
Interface example:
The statement in the context is completely False. The static methods have no
relevance with the objects, and these methods are of the class level. In the case of a
child class, a static method with a method signature exactly like that of the parent
class can exist without even throwing any compilation error.
Although both HashSet and TreeSet are not synchronized and ensure that duplicates
are not present, there are certain properties that distinguish a HashSet from a
TreeSet.
Implementation: For a HashSet, the hash table is utilized for storing the elements in
an unordered manner. However, TreeSet makes use of the red-black tree to store the
elements in a sorted manner.
Complexity/ Performance: For adding, retrieving, and deleting elements, the time
amortized complexity is O(1) for a HashSet. The time complexity for performing the
same operations is a bit higher for TreeSet and is equal to O(log n). Overall, the
performance of HashSet is faster in comparison to TreeSet.
Methods: hashCode() and equals() are the methods utilized by HashSet for making
comparisons between the objects. Conversely, compareTo() and compare() methods
are utilized by TreeSet to facilitate object comparisons.
Objects type: Heterogeneous and null objects can be stored with the help of
HashSet. In the case of a TreeSet, runtime exception occurs while inserting
heterogeneous objects or null objects.
24. Why is the character array preferred over string for storing
confidential information?
In Java, a string is basically immutable i.e. it cannot be modified. After its declaration,
it continues to stay in the string pool as long as it is not removed in the form of
garbage. In other words, a string resides in the heap section of the memory for an
unregulated and unspecified time interval after string value processing is executed.
As a result, vital information can be stolen for pursuing harmful activities by hackers
if a memory dump is illegally accessed by them. Such risks can be eliminated by
using mutable objects or structures like character arrays for storing any variable.
After the work of the character array variable is done, the variable can be configured
to blank at the same instant. Consequently, it helps in saving heap memory and also
gives no chance to the hackers to extract vital data.
25. What are the differences between JVM, JRE and JDK in Java?
HashMap HashTable
HashMap is not synchronized thereby
making it better for non-threaded HashTable is synchronized and hence it
applications. is suitable for threaded applications.
Allows only one null key but any number of This does not allow null in both keys or
null in the values. values.
Supports order of insertion by making use of Order of insertion is not guaranteed in
its subclass LinkedHashMap. HashTable.
The term reflection is used for describing the inspection capability of a code on
other code either of itself or of its system and modify it during runtime.
Consider an example where we have an object of unknown type and we have a
method ‘fooBar()’ which we need to call on the object. The static typing system of
Java doesn't allow this method invocation unless the type of the object is known
beforehand. This can be achieved using reflection which allows the code to scan the
object and identify if it has any method called “fooBar()” and only then call the
method if needed.
Method methodOfFoo = fooObject.getClass().getMethod("fooBar", null);
methodOfFoo.invoke(fooObject, null);
Using reflection has its own cons:
o Speed — Method invocations due to reflection are about three times slower than the
direct method calls.
o Type safety — When a method is invoked via its reference wrongly using reflection,
invocation fails at runtime as it is not detected at compile/load time.
o Traceability — Whenever a reflective method fails, it is very difficult to find the root
cause of this failure due to a huge stack trace. One has to deep dive into the invoke()
and proxy() method logs to identify the root cause.
Hence, it is advisable to follow solutions that don't involve reflection and use this
method as a last resort.
Java always works as a “pass by value”. There is nothing called a “pass by reference”
in Java. However, when the object is passed in any method, the address of the value
is passed due to the nature of object handling in Java. When an object is passed, a
copy of the reference is created by Java and that is passed to the method. The
objects point to the same memory location. 2 cases might happen inside the
method:
Case 1: When the object is pointed to another location: In this case, the changes
made to that object do not get reflected the original object before it was passed to
the method as the reference points to another location.
For example:
class InterviewBitTest{
int num;
InterviewBitTest(int x){
num = x;
}
InterviewBitTest(){
num = 0;
}
}
class Driver {
public static void main(String[] args)
{
//create a reference
InterviewBitTest ibTestObj = new InterviewBitTest(20);
//Pass the reference to updateObject Method
updateObject(ibTestObj);
//After the updateObject is executed, check for the value of num in
the object.
System.out.println(ibTestObj.num);
}
public static void updateObject(InterviewBitTest ibObj)
{
// Point the object to new reference
ibObj = new InterviewBitTest();
// Update the value
ibObj.num = 50;
}
}
Output:
20
Case 2: When object references are not modified: In this case, since we have the
copy of reference the main object pointing to the same memory location, any
changes in the content of the object get reflected in the original object.
For example:
class InterviewBitTest{
int num;
InterviewBitTest(int x){
num = x;
}
InterviewBitTest(){
num = 0;
}
}
class Driver{
public static void main(String[] args)
{
//create a reference
InterviewBitTest ibTestObj = new InterviewBitTest(20);
//Pass the reference to updateObject Method
updateObject(ibTestObj);
//After the updateObject is executed, check for the value of num in
the object.
System.out.println(ibTestObj.num);
}
public static void updateObject(InterviewBitTest ibObj)
{
// no changes are made to point the ibObj to new location
// Update the value of num
ibObj.num = 50;
}
}
Output:
50
In order to achieve this, the attribute can be declared along with the usage
of transient keyword as shown below:
public class InterviewBitExample {
33. What happens if the static modifier is not included in the main
method signature in Java?
There wouldn't be any compilation error. But then the program is run, since the JVM
cant map the main method signature, the code throws “NoSuchMethodError” error
at the runtime.
34. What happens if there are multiple main methods inside one class
in Java?
The program can't compile as the compiler says that the method has been already
defined inside the class.
It is the process of creating an exact copy of any object. In order to support this, a
java class has to implement the Cloneable interface of java.lang package and
override the clone() method provided by the Object class the syntax of which is:
protected Object clone() throws CloneNotSupportedException{
return (Object)super.clone();
}
In case the Cloneable interface is not implemented and just the method is
overridden, it results in CloneNotSupportedException in Java.
When an exception occurs, first it searches to locate the matching catch block. In
case, the matching catch block is located, then that block would be executed. Else,
the exception propagates through the method call stack and goes into the caller
method where the process of matching the catch block is performed. This
propagation happens until the matching catch block is found. If the match is not
found, then the program gets terminated in the main method.
No, it is not necessary for a catch block to be present after a try block. - A try block
should be followed either by a catch block or by a finally block. If the exceptions
likelihood is more, then they should be declared using the throws clause of the
method.
38. Will the finally block get executed when the return statement is
written at the end of try block and catch block as shown below?
public int someMethod(int i){
try{
//some statement
return 1;
}catch(Exception e){
//some statement
return 999;
}finally{
//finally block statements
}
}
finally block will be executed irrespective of the exception or not. The only case
where finally block is not executed is when it encounters ‘System.exit()’ method
anywhere in try/catch block.
39. Can you call a constructor of a class inside the another constructor?
Yes, the concept can be termed as constructor chaining and can be achieved
using this().
40. Contiguous memory locations are usually used for storing actual
values in an array but not in ArrayList. Explain.
In the case of ArrayList, data storing in the form of primitive data types (like int, float,
etc.) is not possible. The data members/objects present in the ArrayList have
references to the objects which are located at various sites in the memory. Thus,
storing of actual objects or non-primitive data types (like Integer, Double, etc.) takes
place in various memory locations.
However, the same does not apply to the arrays. Object or primitive type values can
be stored in arrays in contiguous memory locations, hence every element does not
require any reference to the next element.
Multiple-inheritance is not possible in Java. Classes can only extend from one
superclass. In cases where multiple functionalities are required, for example - to read
and write information into the file, the pattern of composition is preferred. The
writer, as well as reader functionalities, can be made use of by considering them as
the private members.
Composition assists in attaining high flexibility and prevents breaking of
encapsulation.
Unit testing is possible with composition and not inheritance. When a developer
wants to test a class composing a different class, then Mock Object can be created
for signifying the composed class to facilitate testing. This technique is not possible
with the help of inheritance as the derived class cannot be tested without the help of
the superclass in inheritance.
The loosely coupled nature of composition is preferable over the tightly coupled
nature of inheritance.
package comparison;
public class Top {
public int start() {
return 0;
}
}
class Bottom extends Top {
public int stop() {
return 0;
}
}
In the above example, inheritance is followed. Now, some modifications are done to
the Top class like this:
If the new implementation of the Top class is followed, a compile-time error is bound
to occur in the Bottom class. Incompatible return type is there for the Top.stop()
function. Changes have to be made to either the Top or the Bottom class to ensure
compatibility. However, the composition technique can be utilized to solve the given
problem:
class Bottom {
Top par = new Top();
public int stop() {
par.start();
par.stop();
return 0;
}
}
42. How is the creation of a String using new() different from that of a
literal?
The checking() function will return true as the same content is referenced by both the
variables.
Conversely, when a String formation takes place with the help of a new() operator,
interning does not take place. The object gets created in the heap memory even if
the same content object is present.
The checking() function will return false as the same content is not referenced by
both the variables.
Yes, it is possible for the program to go out of memory in spite of the presence of a
garbage collector. Garbage collection assists in recognizing and eliminating those
objects which are not required in the program anymore, in order to free up the
resources used by them.
Moreover, exhaustion of the heap memory takes place if objects are created in such
a manner that they remain in the scope and consume memory. The developer should
make sure to dereference the object after its work is accomplished. Although the
garbage collector endeavors its level best to reclaim memory as much as possible,
memory limits can still be exceeded.
Synchronization assists in resolving the issue and the resource is shared by a single
thread at a time. Let’s take an example to understand it more clearly. For example,
you have a URL and you have to find out the number of requests made to it. Two
simultaneous requests can make the count erratic.
No synchronization:
package anonymous;
public class Counting {
private int increase_counter;
public int increase() {
increase_counter = increase_counter + 1;
return increase_counter;
}
}
With synchronization:
package anonymous;
public class Counting {
private int increase_counter;
public synchronized int increase() {
increase_counter = increase_counter + 1;
return increase_counter;
}
}
If a thread Thread1 views the count as 10, it will be increased by 1 to 11, then the
thread Thread2 will view the count as 11, it will be increased by 1 to 12. Thus,
consistency in count values takes place.
New – When the instance of the thread is created and the start() method has not
been invoked, the thread is considered to be alive and hence in the NEW state.
Runnable – Once the start() method is invoked, before the run() method is called by
JVM, the thread is said to be in RUNNABLE (ready to run) state. This state can also be
entered from the Waiting or Sleeping state of the thread.
Running – When the run() method has been invoked and the thread starts its
execution, the thread is said to be in a RUNNING state.
Non-Runnable (Blocked/Waiting) – When the thread is not able to run despite the
fact of its aliveness, the thread is said to be in a NON-RUNNABLE state. Ideally, after
some time of its aliveness, the thread should go to a runnable state.
o A thread is said to be in a Blocked state if it wants to enter synchronized code but it
is unable to as another thread is operating in that synchronized block on the same
object. The first thread has to wait until the other thread exits the synchronized
block.
o A thread is said to be in a Waiting state if it is waiting for the signal to execute from
another thread, i.e it waits for work until the signal is received.
Terminated – Once the run() method execution is completed, the thread is said to
enter the TERMINATED step and is considered to not be alive.
The following flowchart clearly explains the lifecycle of the thread in Java.
48. Is it possible to import the same class or package twice in Java and
what happens to it during runtime?
49. In case a package has sub packages, will it suffice to import only
the main package? e.g. Does importing of com.myMainPackage.* also
import com.myMainPackage.mySubPackage.*?
This is a big NO. We need to understand that the importing of the sub-packages of a
package needs to be done explicitly. Importing the parent package only results in the
import of the classes within it and not the contents of its child/sub-packages.
NO. The control of the program post System.exit(0) is immediately gone and the
program gets terminated which is why the finally block never gets executed.
Marker interfaces, also known as tagging interfaces are those interfaces that have no
methods and constants defined in them. They are there for helping the compiler and
JVM to get run time-related information regarding the objects.
This is a convenient means of initializing any collections in Java. Consider the below
example.
import java.util.HashSet;
import java.util.Set;
doSomething(stringSets);
}
In the above example, we see that the stringSets were initialized by using double
braces.
The first brace does the task of creating an anonymous inner class that has the
capability of accessing the parent class’s behavior. In our example, we are creating
the subclass of HashSet so that it can use the add() method of HashSet.
The second braces do the task of initializing the instances.
Care should be taken while initializing through this method as the method involves
the creation of anonymous inner classes which can cause problems during the
garbage collection or serialization processes and may also result in memory leaks.
53. Why is it said that the length() method of String class doesn't
return accurate results?
The length method returns the number of Unicode units of the String. Let's
understand what Unicode units are and what is the confusion below.
We know that Java uses UTF-16 for String representation. With this Unicode, we need
to understand the below two Unicode related terms:
o Code Point: This represents an integer denoting a character in the code space.
o Code Unit: This is a bit sequence used for encoding the code points. In order to do
this, one or more units might be required for representing a code point.
Under the UTF-16 scheme, the code points were divided logically into 17 planes and
the first plane was called the Basic Multilingual Plane (BMP). The BMP has classic
characters - U+0000 to U+FFFF. The rest of the characters- U+10000 to U+10FFFF
were termed as the supplementary characters as they were contained in the
remaining planes.
o The code points from the first plane are encoded using one 16-bit code unit
o The code points from the remaining planes are encoded using two code units.
Now if a string contained supplementary characters, the length function would count
that as 2 units and the result of the length() function would not be as per what is
expected.
“bit” would have been the result printed if the letters were used in double-quotes (or
the string literals). But the question has the character literals (single quotes) being
used which is why concatenation wouldn't occur. The corresponding ASCII values of
each character would be added and the result of that sum would be printed.
The ASCII values of ‘b’, ‘i’, ‘t’ are:
‘b’ = 98
‘i’ = 105
‘t’ = 116
55. What are the possible ways of making object eligible for garbage
collection (GC) in Java?
First Approach: Set the object references to null once the object creation purpose is
served.
Second Approach: Point the reference variable to another object. Doing this, the
object which the reference variable was referencing before becomes eligible for GC.
57. Write a Java program to check if the two strings are anagrams.
The main idea is to validate the length of strings and then if found equal, convert the
string to char array and then sort the arrays and check if both are equal.
import java.util.Arrays;
import java.util.Scanner;
public class InterviewBit {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
//Input from two strings
System.out.print("First String: ");
String string1 = s.nextLine();
System.out.print("Second String: ");
String string2 = s.nextLine();
// check for the length
if(string1.length() == string2.length()) {
// convert strings to char array
char[] characterArray1 = string1.toCharArray();
char[] characterArray2 = string2.toCharArray();
// sort the arrays
Arrays.sort(characterArray1);
Arrays.sort(characterArray2);
// check for equality, if found equal then anagram, else not an anagra
m
boolean isAnagram = Arrays.equals(characterArray1, characterArray2);
System.out.println("Anagram: "+ isAnagram);
}
}
Idea is to find the sum of n natural numbers using the formula and then finding the
sum of numbers in the given array. Subtracting these two sums results in the number
that is the actual missing number. This results in O(n) time complexity and O(1) space
complexity.
int[] array={4,3,8,7,5,2,6};
int missingNumber = findMissingNum(array);
System.out.println("Missing Number is "+ missingNumber);
}
Conclusion
61. Conclusion
Java is one of the simple high-level languages that provides powerful tools and
impressive standards required for application development. It was also one of the
first languages to provide amazing threading support for tackling concurrency-based
problems. The easy-to-use syntax and the built-in features of Java combined with the
stability it provides to applications are the main reasons for this language to have
ever-growing usage in the software community.
4.When an object has its own lifecycle and its child object cant belong to another
parent object, what is it called?
Association
Aggregation
Composition
Encapsulation
7.Which of the following happens when the garbage collection process kicks off
during the execution of the thread?
Garbage collection does not happen during thread execution.
Thread pauses while the garbage collection process runs.
Both the process takes place simultaneously and does not interfere its execution.
Nothing happens, the thread proceeds with execution.