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

My All Core Java Interview Questions

The document discusses various concepts in Java including association, aggregation, and composition, explaining their differences and providing code examples. It also covers the Singleton design pattern, detailing how to prevent its violation through reflection, deserialization, and cloning. Additionally, it addresses REST best practices, the differences between authentication and authorization, Java 8 Stream operations, and the benefits of REST over SOAP.

Uploaded by

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

My All Core Java Interview Questions

The document discusses various concepts in Java including association, aggregation, and composition, explaining their differences and providing code examples. It also covers the Singleton design pattern, detailing how to prevent its violation through reflection, deserialization, and cloning. Additionally, it addresses REST best practices, the differences between authentication and authorization, Java 8 Stream operations, and the benefits of REST over SOAP.

Uploaded by

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

Q1.

Association, Composition and Aggregation in Java

Inheritance: - Nothing but parent child Relationship


Association: - In a where Both the object uses each other but they can have their own Life style.
Aggregation: - In a Where there is a single owner of the object.
Composition: - In a where each object depends on each other, if one goes off then the other will also go off so the lifetime
of the objects are same.

Association Code:- (Manager has A swipe card to enter company promises)

Here there is no owner such as both use each other….

1. Both of objects exist independently, and none of them is owner of each other, but they can use each other.
2. Both are separate Entity, and they have their own lifestyle, Manager can stay without swipe-card and swipe-card can
stay without manager.
Aggregation Code :- (Manager has many workers under him)

Now what it says is that means Manager is an owner of the worker in other words workers only belongs to the
owner which means that the Manager have a list of the workers.

Here workers actually belongs to the manager that means the Manager is the Owner of these workers but still
the workers can be created separately, we can create an object of worker without thinking the Manager
means we can still use worker independently.

So, in this kind of relationship, we have one and only one owner like previous swipe card is not the owner of the
manager that can only belongs to.

Composition Code: - (Manager salary depends on project success and the project success depends on
Manager)

Now if the project is successful then manager salary got incremented and now if manager is working properly
then project will be get successful.
Here Manager status is depending on how the project status is going.

So, manager needs the Project object and Project needs the Manager objects both are highly dependable we
can say this one is as a Death Relationship.

Q2. Prevent Breaking a Singleton Class Pattern (Reflection, Cloning and Deserialization)

There are mainly three concepts in which we can break the singleton property of a Singleton class in Java. In
this post, we will discuss how it can break and how to prevent it.
Here is sample Singleton class and SingletonTest class.

Singleton.Java
-------------------
package demo1;
public final class Singleton {
private static volatile Singleton instance = null;
private Singleton() {
}

public static Singleton getInstance() {


if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}

SingletonTest.java
------------------
package demo1;
public class SingletonTest {
public static void main(String[] args) {
Singleton object1 = Singleton.getInstance();
Singleton object2 = Singleton.getInstance();
System.out.println("Hashcode of Object 1 - " + object1.hashCode());
System.out.println("Hashcode of Object 2 - " + object2.hashCode());
}
}

Here is output; you can see it has the same hashcode for objectOne and objectTwo:
Hashcode of Object 1 - 1836019240
Hashcode of Object 2 - 1836019240

>> Now, we will break this pattern. First, we will use Java reflection.

>> Reflection

Java Reflection is an API used to examine or modify the behavior of methods, classes, and interfaces at
runtime. Using the Reflection API, we can create multiple objects in the Singleton class. Consider the following
example:

ReflectionSingleton.java
----------------------------------
public class ReflectionSingleton {
public static void main(String[] args) {
Singleton objOne = Singleton.getInstance();
Singleton objTwo = null;
try {
Constructor constructor = Singleton.class.getDeclaredConstructor();
constructor.setAccessible(true);
objTwo = (Singleton) constructor.newInstance();
} catch (Exception ex) {
System.out.println(ex);
}
System.out.println("Hashcode of Object 1 - "+objOne.hashCode());
System.out.println("Hashcode of Object 2 - "+objTwo.hashCode());
}}
This example shows how reflection can break the singleton pattern with Java reflect. You will get two hash
codes, as shown below. It has a break on the singleton pattern.

Prevent Singleton Pattern from Reflection


---------------------------------------------------------
There are many ways to prevent Singleton pattern from Reflection API, but one of the best solutions is to
throw a run-time exception in the constructor if the instance already exists. In this, we can not able to create
a second instance.

>> Deserialization

In serialization, we can save the object of a byte stream into a file or send over a network. Suppose if you
serialize the Singleton class, and then again de-serialize that object, it will create a new instance, hence
deserialization will break the Singleton pattern.
The below code is used to illustrate how the Singleton pattern breaks with deserialization.

DeserializationSingleton.Java
----------------------------------------
public class DeserializationSingleton {
public static void main(String[] args) throws Exception {
Singleton instanceOne = Singleton.getInstance();
ObjectOutput out = new ObjectOutputStream(new FileOutputStream("file.text"));
out.writeObject(instanceOne);
out.close();
ObjectInput in = new ObjectInputStream(new FileInputStream("file.text"));
Singleton instanceTwo = (Singleton) in.readObject();
in.close();
System.out.println("hashCode of instance 1 is - " + instanceOne.hashCode());
System.out.println("hashCode of instance 2 is - " + instanceTwo.hashCode());
}}
The output is below, and you can see two hashcode
hashCode of instance 1 is - 2125039532
hashCode of instance 2 is – 38125935

Prevent Singleton Pattern From Deserialization


---------------------------------------------------------------
To overcome this issue, we need to override readResolve() method in the Singleton class and return the
same Singleton instance. Update Singleton.java, with below method

protected Object readResolve() {


return instance;
}
Now, run the above DeserializationDemo class and see the output.
hashCode of instance 1 is - 2125039532
hashCode of instance 2 is – 2125039532

>> Cloning

Using the "clone" method, we can create a copy of the original object; it's the same thing if we applied clone in
the singleton pattern. It will create two instances: one original and another one cloned object. In this case, we
will break the Singleton principle, as shown in the below code.
Implement the " Cloneable" interface and override the clone method in the above Singleton class.
Singleton.java
-------------------
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}

Then test with cloning for breaking the singleton.

CloningSingleton.java
------------------------------

public class CloningSingleton {


public static void main(String[] args) throws CloneNotSupportedException, Exception
Singleton instanceOne = Singleton.getInstance();
Singleton instanceTwo = (Singleton) instanceOne.clone();
System.out.println("hashCode of instance 1 - " + instanceOne.hashCode());
System.out.println("hashCode of instance 2 - " + instanceTwo.hashCode());
}}

Here is the output:


hashCode of instance 1 - 1836019240
hashCode of instance 2 - 325040804
If we see the above output, two instances have different hashcodes. This means these instances are not the
same.

Prevent Singleton Pattern from Cloning


------------------------------------------------------
In the above code, it breaks the Singleton principle, i.e created two instances. To overcome the above issue,
we need to implement/override the clone() method and throw an
exception CloneNotSupportedException from the clone method. If anyone tries to create a clone object
of Singleton, it will throw an exception, as shown in the below code.

@Override
protected Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}

Now, we can run the CloningSingleton class; it will throw CloneNotSupportedException while creating a clone
object of the Singleton object .

Q3. Double Hashing (Hashtable initial capacity= 11 HashMap = 16, ArrayList=10)

Double hashing is a collision resolving technique in Hash tables. Double hashing uses the idea of applying a
second hash function to key when a collision occurs.

Double hashing can be done using:

(hash1(key) + i * hash2(key)) % TABLE_SIZE


Here hash1() and hash2() are hash functions and TABLE_SIZE is size of hash table.
(We repeat by increasing i when collision occurs)
First hash function is typically hash1(key) = key % TABLE_SIZE

A popular second hash function is: hash2(key) = PRIME – (key % PRIME) where PRIME is a prime smaller than
the TABLE_SIZE.
A good second Hash function is:
 It must never evaluate to zero
 Must make sure that all cells can be probed

Note:--

When write:-
Map<String,Integer> map=new HashMap<String,Integer>();
By default created Bucket size= 16
List<Integer> list=new ArrayList<Integer>();
By default initial capacity= 10…
After filled all 10 its size increased by 50% so it would be 15

Q4. What are the best Rest Principle you keep in mind when you create REST end
point, the best practises u follows?
a. Don't return plain text
you can verify a reponse's Content-Type very easily with Firefox. It has built-in pretty-display for
responses with Content-Type: application/json.
b. Avoid using verbs in URIs
This is because HTTP verbs should be sufficient to describe the action being performed on the
resource.
# Don't
POST: /articles/createNewArticle/
# Do
POST: /articles/
C. How we can Implement the Bean Validation and Input Request Validation in our Backend
You need to restrict to the user to give the correct inputs, you can do it use Backend. So, no use to
store invalid format data into your db, otherwise it will impact your business.
we just need to mention in the POST Controller method @Valid to validate this particular request
with @Request Body. and for User Request Bean we just need to annotate field with all required
annotation like for name @NotNull, for email @Email, for age @Min(18) and @Max(60) for mobile
@Pattern(^\\d{10}$)
d. Return error details in the response body
When an API server handles an error, it is convenient (and recommended!) to return error details in
the JSON body to help users with debugging. Special kudos if you include which fields were affected
by the error!
{
"error": "Invalid payoad.",
"detail": {
"surname": "This field is required."
}
}
e. Use status codes consistently
400: Bad Request response
404: Resource Not Found
500: Internal server Error
401: UNAUTHORIZED HTTP RESPONSE
403: FORBIDDEN
201: Created
204: No Content
GET: 200 OK
POST: 201 Created
PUT: 200 OK
PATCH: 200 OK
DELETE: 204 No Content
FORBIDDEN: 401

f. Don't nest resources

GET: /authors/12/articles/
GET: /articles/?author_id=12
My recommendation is to use the query string to filter the articles resource directly:
This clearly means: "get all articles for author #12"

g. Make use of the query string for filtering and pagination

GET: /articles/?page=1&page_size=10

h. Learn the difference between 401 Unauthorized and 403 Forbidden


When handling security errors in an API, it's very easy to be confused about whether the error
relates to authentication or authorization (a.k.a. permissions) — happens to me all the time.
Here's my cheat-sheet for knowing what I'm dealing with depending on the situation:
• Has the user not provided authentication credentials? Were they invalid? 👉 401
Unauthorized.
• Was the user correctly authenticated, but they don’t have the required permissions to
access the resource? 👉 403 Forbidden.

Q5. difference between authorization and authentication

Authentication confirms that users are who they say they are. Authorization gives those users
permission to access a resource.
complete an authentication process through:

 Passwords. Usernames and passwords are the most common authentication factors. If a
user enters the correct data, the system assumes the identity is valid and grants access.
 One-time pins. Grant access for only one session or transaction.
 Authentication apps. Generate security codes via an outside party that grants access.
 Biometrics. A user presents a fingerprint or eye scan to gain access to the system.

Authorization in a system security is the process of giving the user permission to access a specific
resource or function. This term is often used interchangeably with access control or client privilege.

Q. Java 8 Stream Intermediate and Terminal Operations?

Java 8 Stream has many operations which can be pipelined together to get desired result. Some
operations produce another stream as a result and some operations produce non-stream values as a
result. The operations which return another stream as a result are called intermediate operations
and the operations which return non-stream values like primitive or object or collection or return
nothing are called terminal operations.

1) The main difference between intermediate and terminal operations is that intermediate
operations return a stream as a result and terminal operations return non-stream values like
primitive or object or collection or may not return anything.

2) As intermediate operations return another stream as a result, they can be chained together to
form a pipeline of operations. Terminal operations cannot be chained together.

3) Pipeline of operations may contain any number of intermediate operations, but there has to be
only one terminal operation, that too at the end of pipeline.

4) Intermediate operations are lazily loaded. When you call intermediate operations, they are
actually not executed. They are just stored in the memory and executed when the terminal
operation is called on the stream.

5) As the names suggest, intermediate operations don’t give end result. They just transform one
stream to another stream. On the other hand, terminal operations give end result.

6) Intermediate Operations :

map(), filter(), distinct(), sorted(), limit(), skip()

Terminal Operations :

forEach(), toArray(), reduce(), collect(), min(), max(), count(), anyMatch(


), allMatch(), noneMatch(), findFirst(), findAny()
Q6. What are the Benefits of REST over SOAP?

SOAP is a standard protocol for creating web services. REST is an architectural style to create web services.

SOAP is acronym for Simple Object Access Protocol. REST is acronym for REpresentational State Transfer.

SOAP uses WSDL to expose supported methods and REST exposes methods through URIs, there are no
technical details. technical details.

SOAP web services and client programs are bind with REST doesn’t have any contract defined between
WSDL contract server and client

SOAP web services and client are tightly coupled with REST web services are loosely coupled.
contract.

SOAP learning curve is hard, requires us to learn REST learning curve is simple, POJO classes can be
about WSDL generation, client stubs creation etc. generated easily and works on simple HTTP methods.
SOAP supports XML data format only REST supports any data type such as XML, JSON,
image etc.

SOAP web services are hard to maintain, any change REST web services are easy to maintain when
in WSDL contract requires us to create client stubs compared to SOAP, a new method can be added
again and then make changes to client code. without any change at client side for existing
resources.

SOAP web services can be tested through programs or REST can be easily tested through CURL command,
software such as Soap UI. Browsers and extensions such as Chrome Postman.

Q7. can we use all HTTP method in soap as well


I always used POST but according to the W3C standard, SOAP supports both POST and GET methods.
Edit: After some research, it seems that it's not completely true, as you can see here. It
is theoretically possible to use GET because POST and GET are methods of HTTP transport protocol
and SOAP can be used over HTTP.
But as you know, GET includes the request in the query string. SOAP requests (XML messages) are
usually too complex and verbose to be included in the query string, so almost every implementation
(for example JAX-WS) supports only POST.

Q8. what is the purpose of service Discovery

Service discovery is how applications and (micro)services locate each other on a network. Service
discovery implementations include both:

o A central server (or servers) that maintain a global view of addresses and
o Clients that connect to the central server to update and retrieve addresses.

Q9. how do you define or setup Eureka Server?

Implementing a Eureka Server for service registry is as easy as:

1. adding spring-cloud-starter-netflix-eureka-server to the dependencies


2. enable the Eureka Server in a @SpringBootApplication by annotating it
with @EnableEurekaServer
3. configure some properties

But we'll do it step by step.


Firstly we'll create a new Maven project and put the dependencies into it. You have to notice that
we're importing the spring-cloud-starter-parent to all projects described in this tutorial:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>Greenwich.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

Note: we can check the latest Spring Cloud releases in the Spring's Projects documentation.
Next, we're creating the main application class:
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
Finally, we're configuring the properties in YAML format; so, an application.yml will be our
configuration file:
server:
port: 8761
eureka:
client:
registerWithEureka: false
fetchRegistry: false

Here we're configuring an application port – 8761 is the default one for Eureka servers. We are
telling the built-in Eureka Client not to register with ‘itself' because our application should be acting
as a server.
Now we'll point our browser to http://localhost:8761 to view the Eureka dashboard, where we will
later inspecting the registered instances.

Q10. what is the use of Hystrix?

A typical distributed system consists of many services collaborating together. These services are
prone to failure or delayed responses. If a service fails it may impact on other services affecting
performance and possibly making other parts of application inaccessible or in the worst case bring
down the whole application.
So, of course, there are solutions available that help make applications resilient and fault tolerant
– one such framework is Hystrix.
The Hystrix framework library helps to control the interaction between services by providing fault
tolerance and latency tolerance. It improves overall resilience of the system by isolating the failing
services and stopping the cascading effect of failures.
In this series of posts, we will begin by looking at how Hystrix comes to the rescue when a service or
system fails and what Hystrix can accomplish in these circumstances.

Q11 JWT (JSON Web Security) Security in Microservices

Commonly used for Authorization. Idea behind JWT is to create a standard way for 2 parties to
communicate securely.

When user first time get login or authorize then browser create a session id and it sends to user with
response and that session id stored to the cookies, next time when user sends subsequent request
then with request header cookies sessionid will come and it says it’s a same user
Now the biggest problem with session id is assume something.
JWT is not for authentication it is for future authorization purpose used for further interactions.
Server says ok I am authenticated you in order to me for remember who you are into subsequent
interaction.

So, JWT is specific to authorization. JWT comes into picture when only authentication is complete.
Server creates the JWT it has the payload, with Header also there and just Signed there and sign is
Strictly associated with the Values which is like JWT- Header and Payload.
When client gets the JWT it can store either in a Local storage or inside the cookies. It doesn’t matter

and client just passes JWT in subsequent Request with HTTP Header, HTTP Headers are key value
pairs. so, the key for passing this according to the JWT standard is called authorization and the value
is the word Bearer followed by space followed by JWT. So, the clients on every subsequent requests
put this in a Header and sends it to the server.
The server examines the request checks this value in Header, says ok the authorization I have the
JWT ,now splits this into 3 parts figures out what the payload is. it just have to do the Base64 Decode
that will give the value. it just has to verify that the value is valid.
It just follows the formula it just does the Base64 Encode of Header and Payload and then it
calculates the signature for It. And verify that it is matches the signature which is generated through
the secret key. If Matches, then It trust. That this JWT with valid signature. If not matches means
Invalid user.

** How secure is a JWT if it is readable by anyone?


No confidential/sensitive information in a JWT. Just enough info for the server to know who
the user is.

** what if someone steals my JWT and uses it themselves?


Server just verifies if JWT is correct, doesn’t know who sent it.

** How do you disable the JWT?

Here there is nothing on the server all are in JWT, u can set an expiration for JWT.
How to do logoff in JWT is tricky, bcz nothing is there onto the server. the people handle this by
some blacklisted JWT, let’s say the server issued me the JWT and I tell the server that somebody
stolen my JWT then what the server can do. on the server its maintain the List of Blacklisted JWT, ok
this particular JWT is blacklisted. if someone try to access with the blacklisted JWT then compare and
say Invalid JWT.

Q12. How do OAUTH flows work?

One service wants to access the second service.


An application making resource requests on behalf of the resource owner and with its authorization .

Few key component->

Resource – Protected Resource


Resource Owner – An Entity capable of granting access to a protected resource.
Resource Server – The Server hosting the protected resources.
Client - An application making resource requests on behalf of the resource owner and with its
authorization.
Authorization Server – The server issuing access tokens to the client.

Who has the burden of security???


The person who has the Resources.
Google Drive has more Responsibility that I am providing right authorization for access.
So, typically the Resource Server has coupled with an Authorization Server. So, Authorization Server making
sure that whoever is access the Resource should be Authorized. So, Google Implement OAuth so, the Google
implements the Authorization Server, which takes care of an Authorization, his responsibility is to make sure
that authorizing is happening fine.

So, Resource server and Authorization server are usually coupled. So, Authorization server could be a
separate server or along with Resource Server.

How it works>>>

Client thinks this guy don’t give me access directly bcz that guy is using OAuth, so first I need to talk
to Authorization Server.
So, Resource owner says yes, I am the only person who ask to access google, so give them access.

Authorization server said OK I got a confirmation from the Resource owner so I am giving a token so
u can access.

Authorization Token - > Auth Token, the client uses this authorization Token and contact the
Authorization server to get a second Token which is the Access Token.
Now the Access Token is like a Key to access the Resource from Resource Server.

Like in Hotel Reception giving the key to access the Room.

UseCase->
OAuth uses for Authorization between services.

What is the application of OAuth for talking between services?


Authorization between microservices…
Microservice1 accessing Microservice2 ….Microservice makes one API call to Microservice2……
Q 13. Difference between @Bean and @Component

Spring supports multiple types of annotations such as @Component, @Controller, @service @Repository and @Bean. All
these can be found under the org.springframework.stereotype package.

When classes in our application are annotated with any of the above-mentioned annotation then during project start up
spring scan (using @componentScan) each class and inject the instance of the classes to the IOC container. Another thing
the @ComponentScan would do is running the methods with @Bean on it and restore the return object to the Ioc
Container as a bean.

Sr. No. Key @Bean @Component

1 Auto detection It is used to explicitly declare a single If any class is annotated with @Component
bean, rather than letting Spring do it it will be automatically detect by using
automatically. classpath scan.

2 Spring Container Bean can be created even class is outside We can’t create bean if class is outside
the spring container spring container

3 Class/Method Level It is a method level annotation It is a class level annotation


Sr. No. Key @Bean @Component

Annotation

4 @Configuration It works only when class is also It works without


annotated with @Configuration @Configuration annotation

5 Use Case We should use @bean, if you want We can’t write specific implementation
specific implementation based on based on dynamic condition
dynamic condition.

Example of @Component
@Component
public class Pizza{
........
}

Example of @Bean
@Configuration
class AppConfiguration{
@Bean
public User getUse(){
return new User();
}
}
Q 14. The hierarchy of exceptions

Exceptions and errors are represented through Java classes, and they are organized in a hierarchy.

The class Throwable is the superclass of all types of errors and of all exceptions. Errors represent
events that cannot be controlled by the programmer (for example, OutOfMemoryError), while
exceptions can be handled during the execution of the program.
Q 15. Difference between @BeforeAll and @BeforeEach

The code marked @Before is executed before each test, while @BeforeClass runs once before the
entire test fixture. If your test class has ten tests, @Before code will be executed ten times,
but @BeforeClass will be executed only once.
In general, you use @BeforeClass when multiple tests need to share the same computationally
expensive setup code. Establishing a database connection falls into this category. You can move code
from @BeforeClass into @Before, but your test run may take longer. Note that the code
marked @BeforeClass is run as static initializer, therefore it will run before the class instance of your
test fixture is created.
In JUnit5, the tags @BeforeEach and @BeforeAll are the equivalents of @Before and @BeforeClass in JUnit 4.
Their names are a bit more indicative of when they run, loosely interpreted: 'before each tests' and 'once
before all tests'.

Q 16. Difference between ClassNotFoundException & NoClassDefFoundError?

Both ClassNotFoundException is an exception and NoClassDefFoundError are the error which occur when
JVM or ClassLoader not able to find appropriate class while loading at run-time.
ClassNotFoundException is a checked exception and NoClassDefFoundError is an Error which comes
under unchecked.

Q 17. How to make our program a thread-safe?


To make Thread safe program: -

 AtomicInteger
 Volatile
 Synchronized method / block
 Thread Local
 Lock/ Reentrant Lock

Q 18. Difference between Interface & Abstract Class?


Interface

Any Service Requirements Specifications (SRS) is by default considered as Interfaces.


Suppose, If I want to develop a web Server that means if I want to run any web application
like jsp or servlet then server must be required. Suppose we can run same application on tomcat or
jetty or resin or WebLogic or WebSphere. So, the question is how we can run same application on
multiple server so the reason is all these people follows same interface or same specifications while
developing this concept. That specification is Servlet API, which is provided by SUN people, these all-
server vendors are responsible to provide the implementations for this specification.
Another example
If any java application want to communicates with Oracle DB or MySQL DB or PostgreSQL DB then
there is one person called Driver, so all Driver must has to Implement JDBC API this jdbc api is called
Service requirements specification or Interface.

Another way-
Any Contract between Client and Service Provider is called Interface. That means what set of
services clients is expecting and what set of services Service provider is providing. that contract
specification is called Interfaces.

*** 100 % pure Abstract class, (but from java 1.8 inside interface default method allow, static
method allow, from java 1.9 private methods are allow) so we can Ignore this.

Abstract Class : Partial Implemented class

 If the Implementation of a class is not complete such type of partially implemented class
declared as an Abstract class.

 If a class contains at least one abstract method, then compulsory that class must be declared as
an Abstract class and Object creation of that class is not possible.

 If a class doesn’t contain any abstract method, then if we feel the class is an inappropriate then
happily, we can declare that class as an Abstract class to restrict the creation of an Object.

 If the Implementation of a class is not complete or dummy Implementation then I don’t want to
create an object of that class then happily we should declare that class as an Abstract even
though that class doesn’t have any abstract method, because no use to creation of an object.
Example:-

Abstract class Test


{
Public void m1(){ };
Public void m2(){ };
}
Test t=new Test();
t.m1();

So, if a class declared as Abstract means partially Implemented class… so if you feel the implementation of a
class is inappropriate or improper then we can happily declare that type of class as Abstract class.
If I declared a class as an Abstract, then no one is allowed to create the Object or no one is allowed to call
these methods.
Example

*** Adapter class doesn’t contain any Abstract methods then also they declared as an Abstract, bcz some methods
having only curly open and close braces so no use.

*** HttpServlet class: even this class also not contains abstract methods.

Difference between Interface and Abstract Class

Interface Abstract Class

1. If we don’t know anything about Implementation just, 1. If we are talking about Implementation but not
we have requirement specification then we should go completely (partial Implementation) then we should go
for Interface. for Abstract class.
2. Inside Interface every method is always public and 2 Every method present in Abstract class need not be
abstract whether we are declaring or not. Hence public and abstract, It can contains concrete methods
Interface is also considered as 100% pure abstract also.
class.
3. We can’t declare interface method with the following 3 There are no restrictions on Abstract class method
modifiers. modifiers.
Public  private, protected
Abstract- final, static, synchronized, native, strictfp
4. Every variable present inside interface is always public, 4 The variables present inside Abstract class need not be
static and final whether we are declaring or not. public static and final.
5. Transient keyword not applicable with Interface bcz
Serialization not applicable for Interface bcz we can’t
create object for interface.
6 We can’t declare interface variables with the following 6 There are no restrictions on Abstract class variable
modifiers. modifiers.
Private, protected, transient, volatile (bcz it is final so can’t
volatile means keep on changing)
7 for Interface variables compulsory we should perform 7 for Abstract class variables it is not required to perform
initialization at the time of declaration otherwise we ll get initialization at time of declaration.
compile time error.
So int x; // will throw error

8 Inside Interface we can’t declare instance and static blocks 8 Inside Abstract class we can declare instance and static
otw we ll get compile time error. blocks.

9. Constructor concept not applicable for Interface bcz the 9 Inside Abstract class we can declared constructor which
purpose of constructor is initialized the instance variables will be executed at the time of child object creation.
but within an interface every variables is always static and
initialized .

Q 19. What are 4 OOPS principal in java?

Encapsulation - encapsulation means data hiding + Abstraction,


Abstraction - Abstraction means hiding the implementation,
Inheritance - Inheritance is a process where child class acquires the properties of super class, and
Polymorphism -
Compile time polymorphism - can be achieved by using Method overloading &
Runtime polymorphism - Runtime polymorphism can be achieved by using Method
overriding

1. Encapsulation: - data hiding + Abstraction

 Data hiding means outside persons should not access our data directly by declaring private variable or by declaring
our variable at the private we can implement data hiding.
 Abstraction means hiding Internal Implementations just highlight the setup services what we are offering is a concept
of abstraction.

 If u are feeling cold, then immediately we are going to use cold act capsule. So, some medicine will be there inside the
capsule. So whatever medicine required to cure the cold that medicine is encapsulated.so medicine is going to be
grouped inside the capsule.so it is going to be grouped or a single unit of medicine inside the capsule…

Class Student
{
String name;
Int age;
Int marks;
+
Read();
Write();
}

The process of Grouping or combining data members and corresponding methods or behavior into a single unit is a
concept of encapsulation. So capsule means grouping mechanism.
So, every java class is an example of Encapsulation.
Now Practically,

If any Component follows data hiding and abstraction that component is said to be encapsulated component.

Encapsulation:- data hiding + Abstraction

Class Account
{
Private double balance;
Public double getBalance()
{
//validate (uname and pwd either person is correct person or not)

If person is valid
return balance;
}

Public void setBalance(double amount)


{
//validation
If this is deposit
This.balance=this.balance+amount;
}

So here bcz of private outside person can’t access the account balance so how outside person can access for that we are
providing the getter and setter methods. So, the benefit of access data from setter and getter is the required validations. So
outside person only to get the data either the setter or getter operation after the required validations.

So now if we are saying


Encapsulation:- data hiding + Abstraction
So compulsory it should follow the data hiding and abstractions.
So where is data hiding, declare the variable as a private is data hiding. But where is abstraction…? How can u say yes
abstraction is there in Account example----
So, I never going to be highlights this get balance and set balance functionality to outside person directly.
So, I will provide some GUI base screen may be jsp or spring base. In that balance enquiry button, another button deposit.
Whenever end user click balance Enquiry now getBalance () will be executed. when clicked Deposit(0 then setBalance will
be execute. But end user doesn’t know which method or which code is executing. we never going to highlight the internal
implementations. So, data hiding and abstraction which is nothing but encapsulation.

Summary: -
1. Grouping data members and corresponding methods into a single unit is a concept of Encapsulation.
2. If any Component follows data hiding and abstraction that component is said to be encapsulated
component.
3. So, declare members as a private and for every data member provide getter and setter methods and
we can provide access through GUI screen called Encapsulation.
4. So through getBalance () and setBalance () only we are going to provide the data so getBalance () and
setBalance() is either Interface for outside persons….internally our data is going to comes so that’s y
hiding the data behind the methods.
5. So, Hiding the data inside the methods is called encapsulations.
6. Advantage: - 1. security achieve 2. Enhancement – we can perform any type of changes internally….
3. Maintainability and Modularity.
7. Disadvantage: every member req setter and getter…and validations required so more no . of line of
code slow execution so wherever security required then only go to use Encapsulation.

2. Abstraction:-

Hiding Internal Implementation just highlights the set of services what we are going to offer is the
concept of abstraction. By using GUI concepts or some Interfaces we can Implements the
Abstractions. Using GUI, we can maintain the abstraction
Example: - ATM GUI Screens
when we are going to ATM machine…

ATM GUI Screen

We don’t know after withdraw which query is going to execute.


Bank People through GUI ATM screen they are going to highlights the set of services what they are
offering …
Advantage: 1. Security- Wherever hiding is there the biggest is Security
2. Outside person don’t aware with internal implementations
3. Without effecting the end-user we can able to perform any internal implementations
in our designs…
4. Enhancement will become very easy without effecting end-user.
5. Maintainability of the application is going to improve.
6. Modularity.

We can change technology itself by maintaining same GUI frame. In ATM when click on withdraw
previously written code in java again new technology came YAVA….so only we can change our
internal implementations without changing GUI itself.
3. Polymorphism

One name but multiple forms, (Polytechnique means many technologies are coming)
Method Overloading and Method Overriding is the best example for the Polymorphism.

package com.home.java;
public class Parent
{
public static void foo() {
System.out.println("Inside foo method in parent class");
}

public void bar() {


System.out.println("Inside bar method in parent class");
}
}

package com.home.java;
public class Child extends Parent
{
// Hiding
public static void foo() {
System.out.println("Inside foo method in child class");
}

// Overriding
public void bar() {
System.out.println("Inside bar method in child class");
}
}

package com.home.java;
public class MainApp
{
public static void main(String[] args) {
Parent p = new Parent();
Parent c = new Child();
System.out.println("****************Method Hiding*******************");
p.foo(); // This will call method in parent class
c.foo(); // This will call method in parent class
System.out.println("****************Method overriding*******************");
p.bar(); // This will call method in parent class
c.bar(); // This will call method in child class

}
}

output:-

****************Method Hiding*******************
Inside foo method in parent class
Inside foo method in parent class
****************Method overriding*******************
Inside bar method in parent class
Inside bar method in child class

4. Inheritance: -

Inheritance is a process where child class acquires the properties of super class.

We can generate Thread Dump…either J VisualVM, which Is under jdk or through command
prompt using Jstack…..

Vector will grow 100% of its size when ArrayList 50% of his size.
Vector - Synchronized
ArrayList: - Not Synchronized

Fork-Join Pool:-

Exactly the same as ExecutorService….Internally just uses double ended queue for each of the
threads…
And all of the sub-tasks that each thread produces they are all stored into their all double ended queue…..
How to submit that tasks to Executor service

No changes now if u work with fork join tasks, then u have to use these special methods……
So, Fork join Task is a class build internally, to create a kind of task which can produce sub tasks.
how ForkJoinPool works
https://www.youtube.com/watch?v=5wgZYyvIVJk

Java ExecutorService - Part 1 - Introduction


https://www.youtube.com/watch?v=6Oo-9Can3H8

Java ExecutorService - Part 2 - Type of Pools


https://www.youtube.com/watch?v=sIkG0X4fqs4

Java ExecutorService - Part 4 - Callable / Future


https://www.youtube.com/watch?v=NEZ2ASoP_nY

As volatile keyword is not cached in CPU, it is always read from main memory, so in terms of performance it’s always expensive to use
volatile keyword.

Can subclass avoid Serialization if its superClass has implemented Serialization interface in java

If superClass has implemented Serializable that means subclass is also Serializable (as subclass always inherits all features
from its parent class), for avoiding Serialization in sub-class we can define writeObject() method and throw
NotSerializableException() from there as done below.

private void writeObject(ObjectOutputStream os) throws NotSerializableException


{
throw new NotSerializableException("This class cannot be Serialized");
}

To visualize this->
When we are submitting a task for callable, it immediately giving the placeholder value, which will give the
future value bcz service.submit won’t give result after submit it will give in future….but it will give the
placeholder value from which we can get result by future.get() method.

When we used future.get () doing the Blocking operation, when we call future.get () from main thread it will block the main
thread to perform any task once pool returns the placeholder value then main thread and runnable. When we have
submitted more tasks to pool submitted 4 tasks then pool won’t guarantee that task one will complete before 3 and task 4.

the problem was Even though there are many tasks which has been completed since we are using a for loop
for future.get () we are not be able to do anything from 7 and 5. Until the value 1st task is completed.
Let’s take one example
Let’s say we have certain set of code which divided into certain methods and each method is responsible for the
particular task. So, let’s we have a method for above all so for an order flow we have 5 particular tasks.

So here these all blocking the main thread until future is not completed future.get() if one or 2 tasks
completed we are not be able to do anything until all tasks completed.

It is like sequential operation if there is a dependency on Enrich order of Fetch order bcz enrich order
can’t work until fetch order is completed so there is some certain dependency for these tasks. If multiple threads
running like one doing fetch order another doing enrich order.

So, if we need the scale of our ordering process what I want is we want say n number of threads, in this
case 10 threads all doing the processing for one particular flow. So, we need independent flow so in one flow
tasks are dependent on each other but one flow can’t depends on another flow.
We don’t even care how the task is executing and most important thing is we don’t want main thread to be
block. This is what exactly completable future are designed for.

So previous code we have converted into CompletableFuture.

 we can say that reference to object is passed by copy in java


 Reference to object is passed by value (i.e. copy of reference is created and passed), reference to object is not at all
passed by reference in java.

Class Level Lock: - Its mainly used to make static level data thread safe.
Object level Lock: - This can always be done to make instance-level data thread-safe.

What is serialVersionUID? Impact of not defining serialVersionUID in class and avoiding InvalidClassException in
java

serialVersionUID is used for version control of object.


If we don’t define serialVersionUID in the class, and any modification is made in class, then we won’t be able to deSerialize our class
because serialVersionUID generated by java compiler for modified class will be different from old serialized object . And
deserialization process will end up throwing java.io.InvalidClassException (because of serialVersionUID mismatch)

How to avoid NotSerializableException?


We got to ensure that during Serialization all the members of class implements Serializable.
Can list, set and maps be Serialized and DeSerialized in java

ArrayList, HashSet and HashMap implements Serializable interface, so if we will use them as member of class they will get Serialized and
DeSerialized as well.

Is constructor of class called during DeSerialization process in java

It depends on whether our object has implemented Serializable or Externalizable.

If Serializable has been implemented - constructor is not called during DeSerialization process.
But, if Externalizable has been implemented - constructor is called during DeSerialization process.

What is busy spin?


When one thread loops continuously waiting for another thread to signal.

What is CountDownLatch in java?


There might be situation where our thread to wait until one or more threads completes certain operation.
A CountDownLatch is initialized with a given count.
count specifies the number of events that must occur before latch is released.
Every time an event happens count is reduced by 1. Once count reaches 0 latch is released.

Application of CountDownLatch in real world >


When you go in amusement park, you must have seen on certain rides there is mandate that at least 3 people ( 3 is count)
should be there to take a ride. So, ride keeper (ride keeper is main thread) waits for 3 persons (ride keeper has called
await()).
Every time a person comes count is reduced by 1 (let’s say every person is calling countDown() method). Ultimately when
3 persons reach count becomes 0 & wait for ride keeper comes to end.

In short about CountDownLatch’s await () and countDown () method in java >


The await () methods block the current threads until the count reaches 0 due to invocations of the countDown() method
by some other thread, after which blocked threads are released.

2) Program to demonstrate usage of CountDownLatch in java >


import java.util.concurrent.CountDownLatch;
class MyRunnable implements Runnable{

CountDownLatch countDownLatch;

MyRunnable(CountDownLatch countDownLatch){
this.countDownLatch=countDownLatch;
}

public void run(){

for(int i=2;i>=0;i--){

countDownLatch.countDown();
System.out.println(Thread.currentThread().getName()+
" has reduced latch count to : "+ i);

try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

}
public class CountDownLatchTest {

public static void main(String[] args) {


CountDownLatch countDownLatch=new CountDownLatch(3);
System.out.println("CountDownLatch has been created with count=3");

new Thread(new MyRunnable(countDownLatch),"Thread-1").start();


try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println("count has reached zero, "+


Thread.currentThread().getName()+" thread has ended");
}
}
/*OUTPUT
CountDownLatch has been created with count=3
Thread-1 has reduced latch count to : 2
Thread-1 has reduced latch count to : 1
Thread-1 has reduced latch count to : 0
count has reached zero, main thread has ended
*/

2.1) Let’s discuss output in detail, to get better understanding of CountDownLatch usage in program in java >
Note: I have mentioned output in green text.

CountDownLatch has been created with count=3


Initially, CountDownLatch is created with count=3
main thread called countDownLatch.await() and it is waiting for count to become 0.
Thread-1 called countDownLatch.countDown() method. [Now, count=2]
Thread-1 has reduced latch count to : 2
Thread-1 called countDownLatch.countDown() method. [Now, count=1]
Thread-1 has reduced latch count to : 1
Thread-1 called countDownLatch.countDown() method. [Now, count=0]
Thread-1 has reduced latch count to : 0
count has reached zero, main thread has ended
As, count has reached zero, main thread has ended.

To make Thread safe program: -


1. AtomicInteger
2. Volatile
3. Synchronized method / block
4. Thread Local
5. Lock/ Reentrant Lock

What is java.util.concurrent.CyclicBarrier in java?


There might be situation where we might have to trigger event only when one or more threads completes certain
operation.
2 or more threads wait for each other to reach a common barrier point. When all threads have reached common barrier
point (i.e. when all threads have called await() method) >
 All waiting threads are released, and
 Event can be triggered as well.

package CyclicBarrier;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierTest {
public static void main(String[] args) {
/*
* Create CountDownLatch with 3 parties, when all 3 parties
* will reach common barrier point CyclicBarrrierEvent will be
* triggered i.e. run() method of CyclicBarrrierEvent will be called
*/
CyclicBarrier cyclicBarrier=new CyclicBarrier(3 ,new CyclicBarrrierEvent());
System.out.println("CountDownLatch has been created with parties=3,"
+ " when all 3 parties will reach common barrier point "
+ "CyclicBarrrierEvent will be triggered");
MyRunnable myRunnable1=new MyRunnable(cyclicBarrier);

//Create and start 3 threads


new Thread(myRunnable1,"Thread-1").start();
new Thread(myRunnable1,"Thread-2").start();
new Thread(myRunnable1,"Thread-3").start();
}
}
class MyRunnable implements Runnable{
CyclicBarrier cyclicBarrier;
MyRunnable(CyclicBarrier cyclicBarrier){
this.cyclicBarrier=cyclicBarrier;
}

@Override
public void run() {

System.out.println(Thread.currentThread().getName() +
" is waiting for all other threads to reach common barrier point");
try {
Thread.sleep(1000);
/*
* when all 3 parties will call await() method (i.e. common barrier point)
* CyclicBarrrierEvent will be triggered and all waiting threads will be released.
*/
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}

System.out.println("As all threads have reached common barrier point "


+ Thread.currentThread().getName() +
" has been released");
}

}
class CyclicBarrrierEvent implements Runnable{
public void run() {
System.out.println("As all threads have reached common barrier point "
+ ", CyclicBarrrierEvent has been triggered");
}
}
/*OUTPUT
CountDownLatch has been created with parties=3, when all 3 parties will reach common barrier point CyclicBarrrierEvent will be triggered
Thread-1 is waiting for all other threads to reach common barrier point
Thread-2 is waiting for all other threads to reach common barrier point
Thread-3 is waiting for all other threads to reach common barrier point
As all threads have reached common barrier point , CyclicBarrrierEvent has been triggered
As all threads have reached common barrier point Thread-1 has been released
As all threads have reached common barrier point Thread-3 has been released
As all threads have reached common barrier point Thread-2 has been released
*/

Similarity and Difference between CyclicBarrier and CountDownLatch in Java

1. First let’s discuss Similarity between CyclicBarrier and CountDownLatch in Java. CyclicBarrier and CountDownLatch are
similar because they wait for specified number of thread to reach certain point and make count/parties equal to 0.
But, for completing wait in CountDownLatch specified number of threads must call countDown () method in Java. for completing wait in
CyclicBarrier specified number of threads must call await () method in Java.

Let’ see their constructor’s in Java >

CountDownLatch(int count) CyclicBarrier(int parties)


CountDownLatch is initialized with given New CyclicBarrier is created where parties number of thread wait for each other to reach
count. common barrier point, when all threads have reached common barrier point, parties
count specifies the number of events that number of waiting threads are released.
must occur before latch is released.

3. This is very important difference between CyclicBarrier and CountDownLatch in java . CyclicBarrier can be awaited repeatedly, but
CountDownLatch can’t be awaited repeatedly. i.e. once count has become 0 cyclicBarrier can be used again but CountDownLatch cannot
be used again in Java.
4. Another important difference between CyclicBarrier and CountDownLatch in java. CyclicBarrier can be used to trigger event, but
CountDownLatch can’t be used to launch event. i.e. once count has become 0 cyclicBarrier can trigger event in Java but CountDownLatch
can’t.
What is java. util.concurrent.locks.Lock in java?

The java.util.concurrent.locks.Lock is an interface, and its implementations provide more extensive locking operations than
can be obtained using synchronized methods and statements.
A lock helps in controlling access to a shared resource by multiple threads. Only one thread at a time can acquire the
lock and access the shared resource.
If a second thread attempts to acquire the lock on shared resource when it is acquired by another thread, the second
thread will wait until the lock is released. In this way we can achieve synchronization and race conditions can be avoided.

Lock interface important methods in java >


void lock()
Acquires the lock if it is not held by another thread. And sets lock hold count to 1.
If current thread already holds lock then lock hold count is increased by 1.
If the lock is held by another thread then the current thread waits for another thread to release lock.
void unlock()
If the current thread is holding the lock then the lock hold count is decremented by 1. If the lock hold count has reached
0, then the lock is released.
If lock hold count is still greater than 0 then lock is not released.
If the current thread is not holding the lock then IllegalMonitorStateException is thrown.
boolean tryLock()
Acquires the lock if it is not held by another thread and returns true. And sets lock hold count to 1.
If current thread already holds lock then method returns true. And increments lock hold count by 1.
If lock is held by another thread then method return false.
int getQueueLength()
Method returns number of threads that may be waiting to acquire this lock.
Method is used just for monitoring purposes and not for any kind of synchronization purposes.
boolean isHeldByCurrentThread()
Method returns true if lock is held by current thread. Its similar to Thread.holdsLock() method.

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockTest {
public static void main(String[] args) {
Lock lock=new ReentrantLock();
MyRunnable myRunnable=new MyRunnable(lock);
new Thread(myRunnable,"Thread-1").start();
new Thread(myRunnable,"Thread-2").start();

}
}

class MyRunnable implements Runnable{


Lock lock;
public MyRunnable(Lock lock) {
this.lock=lock;
}
public void run(){

System.out.println(Thread.currentThread().getName()
+" is Waiting to acquire lock");

lock.lock();
System.out.println(Thread.currentThread().getName()
+" has acquired lock.");

try {
Thread.sleep(5000);

System.out.println(Thread.currentThread().getName()
+" is sleeping.");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+" has released lock.");
lock.unlock();
}
}
/*OUTPUT
Thread-1 is Waiting to acquire lock
Thread-2 is Waiting to acquire lock
Thread-1 has acquired lock.
Thread-1 is sleeping.
Thread-1 has released lock.
Thread-2 has acquired lock.
Thread-2 is sleeping.
Thread-2 has released lock.
*/

6.1) Let’s discuss output in detail, to get better understanding of ReentrantLock usage in program in java >
Note : I have mentioned output in green text.

Thread-1 is Waiting to acquire lock


Thread-2 is Waiting to acquire lock
Thread-1 and Thread-2 are waiting to acquire lock.

Thread-1 has acquired lock.


Thread-1 has acquired lock by calling lock() method. (Now lock hold count=1)
Thread-2 has also called lock() method, but it will have to wait until lock hold count becomes 0. (lock hold count will become 0 when
Thread-1 will call unlock() method)

Thread-1 is sleeping.
Thread-1 has released lock.
Thread-1 has released lock by calling unlock() method. (Now lock hold count=0)

Thread-2 has acquired lock.


Thread-2 has acquired lock by calling lock() method. (Now lock hold count=1)

Thread-2 is sleeping.
Thread-2 has released lock.

JVM (Java Virtual Machine) Architecture


Class Loading Subsystem

Loading
 you have bootstrap class loader, which is responsible for loading Java's internal classes.
So where does that internal class reside? The internal classes are inside the rt.jar that is
distributed with your JVM implementation. So, just go to the JRE folder and you might
find the rt.jar under there. So that is the bootstrap class loader.
 Now going into extension class loader i.e the second-class loader that gets executed
which is responsible of loading additional application jars that are present in jre/lib/ext
folder. So, whatever jars that are present in jre/lib/ext folder is extension class loader. It
will load and read all the dot class files from those jars and give it out for the further
processing.
 So, last class loader is application class loader. The application class loader loads classes
from values specified in your classpath environment variable and if you specify a minus
CP parameter with the Java command, the application class loader loads classes from that
minus CP parameter as well. So those are the three different class loaders in the load
phase.

Linking
So going on to the next phase, which is the link phase. So, the link phase is where a lot of
work is done. The link phase itself has three different phases.
<>First is verify. <>Second is prepare. <>Third is resolve.
 The verify phase basically looks at the bytecode that is loaded by the class loader and
checks if that is compatible to the JVM class specification and things like that. So, that is
the verification phase. So, you have to first verify the bytecode that is handed to me if it is
a valid Java bytecode. So, that is the class verification.
 Once it is verified, the prepare step happens. So, the prepare step is the place where
memory is allocated for the static variables inside a class file. So, you might have private
static integer So, it's a class level variable. So, the memory for that class level variable is
allocated in the prepare phase. So, the most important point that you should note at this
point is that it's only memory allocation that is happening and that is only for the class
variables, not for the instance variables. So, since it is just the memory allocation what
happens is those memory locations are initialized to default values. Suppose you have a
variable like public static boolean isCorrect=true. But at prepare phase, memory will
be allocated for boolean, and it will be set to its default value, which is false as per JVM
specification.
 Now comes the resolve phase. So, the resolve phase is the place where all the symbolic
references inside the current class are resolved. "Symbolic references" are strings that
can be used to retrieve the actual object . Suppose you have references to other classes or
references to values in the constant pool. These are changed from symbolic to the actual
reference.
So, those are the three steps involved in link phase, which is verify, prepare and resolve.

Initialize
The next phase of class loading subsystem is initializing. So, this is the phase where static
initializers of your class is run. Suppose you have a static block, static open parenthesis, close
parenthesis. Anything under that static block is executed at this initialized phase and
wherever you have set values for static variables, those values are set into the memory
location at this phase. So, in the prepare phase, for example we talked about a public boolean
is correct equal to true. So, when its memory was allocated, it was set to false initially and
now in the initialized phase, its actual value that we mentioned in the code is set to that
memory area. So those are the three different phases involved in class loading.

Note: -
There is a bit of detail that we might be interested in this area. For example,
ClassNotFoundException. So, ClassNotFoundException happens when the class loader
fails to find the bytecode corresponding to a class we mentioned. It's as simple as that and
there is another type of exception called ClassDefNotFound, ClassDefNotFound generally
happens during a resolve phase where you try to suppose I'm loading a class X. And suppose
we went through this loading phase, and we went to the link phase, it went through the verify
because X's bytecode looks pretty good, and X is prepared. Now, suppose X is referring to
another class called Y at the resolve phase, the system tries to find out class Y because X is
referring to Y. So, if class Y cannot be found, an exception will be thrown called
ClassDefNotFound for X, which wraps ClassNotFoundException for Y. So those are some
certain exceptions that are attached to the class loading. So now we talked about class loader
subsystem and its phases.

Run-Time data Areas


Now let's go to the runtime data areas. The memory of Java virtual machine. So, the runtime
data areas basically have five different areas.

Method Area

 First is the Method Area. The method area is the place where class data, the metadata
corresponding to class is stored. A lot of APIs in Java reflection API for class, the class
class, inquires data in the method area.
 So, you have the static variables, you have the bytecode, you have the class level constant
pool. everything is stored in the method area.
 So, method area is basically, you know, is the memory allocated to the JVM. It is created
when the JVM starts, and it is destroyed only when the JVM exits.
 So, the method area is called the permgen space. So, the permgen space is the place by
default, 64 megabytes, 64 MB is allocated for method area or permgen. So, this can be
tuned. Suppose your application is a huge server application that loads a lot of classes,
millions of classes. In that case, you will have to tune the permgen using XX:
MaxPermSize and you can set it to a certain MB or GB as you might need it. Right. So,
suppose your application has the permgen is very, very low corresponding. Suppose
you're trying to load a million classes, but you never talked about MaxPermSize. I
suppose you left it at 64 MB. So, your application might run into
Java.lang.OutOfMemoryError for permgen space.
 So, since Java 8, they have gotten rid of the method area or the permgen, which is called
now the metaspace in Java 8. So, what they've done is moved the permgen or method
area into a separate memory in the native operating system and that is called the
metaspace. So, the point is, by default, there is no limit to metaspace in Java 8. So, you
can just grow as long as it can grow based on the operating system. It can just go grow
and occupy full memory or it can go to the virtual memory and things like that. So that's
the difference between permgen and metaspace and metaspace again can be tuned, can be
limited. Suppose you don't want it to just grow. You can limit using a certain JVM
parameter that you can check out on the Java 8 JVM Java command options.

Heap
 Now coming over to the next runtime data area, which is Heap. Heap is a very popular
memory area in JVM, and you would have come across a lot of things to do with heap,
like OutOfMemoryError for heap, etc. A lot of people might have seen in their life.
 So, heap is a place where object data is stored. So, every time you instantiate an object,
suppose you recall something like MyApp app=new MyApp, that object is created in the
heap. So, anything to do with object is created in the heap.
 So, all the instance variables, arrays, everything is since arrays are objects are created in
heap. So, heap is a very important memory area in Java.
 That most of the time needs to be tuned based on your application requirements. So that
is tuned using minus -Xms for the minimum size and minus -Xmx for the maximum size.
So, you can tune it using your parameters and adjust it as the application needs.

PC Registers
 PC register is basically program counter registers. So, it contains program counter, which
is the pointer to the next instruction to be executed Per thread. So, suppose in this case,
we are running 3 threads T1, T2 and T3. So, there will be program counter created for T1
pointing to the next instruction for thread one T2 pointing to the next instruction for T2
and T3 pointing to the next instruction for T3. All these three will be created in the
program counter registers. So, that is per thread.

 Now Java stacks. Java stacks contains stack frame corresponding to the current method
execution per thread. Suppose we have a thread that is executing 3 methods. So, the Java
stack for that thread, this is T1 in this case, this is T2, and this is T3. So, T1 has three
method executing currently so it would have pushed. Suppose this method calls this
method and this method. So, it will have pushed first stack frame corresponding to first
method. Suppose method one is called method two. So, it would push the stack frame
corresponding to method two into the stack. Suppose this method two is called method
three. So, it'd push the stack frame corresponding to method three into the stack. So, and
it'll be popped based on how it is returning, So, this is per thread and stack frame
basically contains data related to the currently executing method.

 suppose one of our method is invoking a native method. So that's why that's the point
when native methods stack come into picture. So, at that point of time, a native method
stack will be created for that native method that you're calling.
 Stack basically is per method invocation, as I said, the stack frames. So, let's think about a
recursive algorithm and, you know, recursive methods, as you know are the method that
call itself for example factorial. So, the recursive method calls itself. Suppose we forgot
to put the exit condition or they call it the basic condition of the recursion so that it can be
returned. Right. Suppose we forgot to mention the exit criteria for recursion. So, what
happens? Your method calls itself infinitely. So as a result, what will happen? Stack
frame for each invocation will be pushed into this stack. So, you know, it will keep on
adding stack frame over stack frame or stack frame over stack frame. And as a result,
what will happen is this memory area, this data area will run out of memory and when
that happens, you will get this exception called Java.lang.stackoverflow Error.
whenever the stack overflow error happens, you have to look for some recursive type
calls that are going to push, keep on pushing stack frames and never popping them, never
returning out of co-ops. So, you would have to look for that type of scenario to resolve
that issue and maybe there are certain genuine cases where you might have to tune your
Java stacks. So, in that case, what you would use is the -Xss parameter as shown here.

Execution Engine

Now let's go to the final point, which is the execution engine. So once. The data area is loaded with
the instruction to be executed. What happens is that the Java interpreter interprets the current
instruction that is there in the bytecode and executes it. So, the execution engine, you know, in a
broad sense, has the following components that is interpreter. Then there is JIT compiler, just in time
compiler, hotspot profiler and garbage collector.

Compiler VS Interpreter

Compiler Interpreter
o It scans the entire programs first and translates it o It scans the program line-by-line and translates it
into machine code. into machine code.
o Compiler shows all errors & warning at same o Interpreter shows one error at a time.
time.
o Error occurs after scanning the whole programs. o Error occurs after scanning each line.
o Debugging is slow bcz if error occurs we don’t o Debugging is faster.
know at which line error occur.
o Execution time is less. o Execution time is more.
o Compiler is used by language such as c, c++ etc. o An Interpreter is used by language such as java,
python etc.

JIT Compiler
 JIT stands for Just-In-Time Compiler. JIT is a part of JVM.
 The actual use of JIT is to compile the bytecode to machine code at a runtime. JIT converts the
bytecode into a machine code at a runtime and performs some optimization on code so that
code can be executed very fast and improve the performance of execution at the runtime if
some program contains one instruction or a method which can be executed more than a
thousand times. At that time, in traditional JVM, the JVM used to read the instructions and
convert that instruction into a machine code and execute that instruction on a CPU. Every time
that instruction occurs, it is converting into a machine code and then it is executed on a
machine. But it is time-consuming. Every time it needs to convert it into a machine code.
 So, Java developer finds some solution and implemented a JIT compiler. So, what JIT compiler
will do? The JIT compiler will check at the runtime that which instruction is executing multiple
times. It will compile that instruction and keep it into a memory so that next time the same
instruction or method occurs, it will pick the method from that memory and no need to
recompile that method or convert that method into a machine code. So, ultimately, this will
improve the execution time of a program.

 also, the JIT compiler has some inbuilt optimization methods so that it looks for a code that it
checks if some code has some part of code or instruction that are not used, or they are just
written badly. That is some expression is written but we are not using that instruction and we
are just assigning like we have some instruction like A=A+B and we are not using the result of A
or displaying the result of A anywhere. So, what JIT will do? JIT will eliminate this instruction and
it will not compile the instruction at a runtime so that it will ultimately increase the performance
of execution. This is how the JIT will improve the Java performance of execution.

Summary:

So, first is the class loader subsystem. Second is the runtime data areas. Third is the execution engine and class
loader subsystem have load, link, initialize and load is for the class loaders. Link has three different steps. You
can go into details later and initialize initializes runs the static initializes and the runtime data area, you have
five different data areas, which is basically the memory space allocated for JVM, which is method area for class
data heap for object data. Java stack per thread keeps track of currently executing method and its data and PC
registers per thread, the program counters that knows what execution, what operation to execute next and
native methods stacks corresponding to native methods used by the application and execution engine. We
saw as the interpreter just in time compiler, compiler, hotspot profiler, which is sometimes they call it the
hotspot VM. Then you have the garbage collector, which interfaces with the native libraries through native
method interfaces. That summarizes the JVM architecture.
Garbage Collection in Java

How garbage collection works in Java and what are the garbage collectors are there and what are the purpose of
those and how to use them.
o Java provides automatic memory management through a program/thread called garbage collector
o live object = reachable (referenced by another object or someone else in your Application)
o dead object = unreachable (not referenced from anywhere)
o Objects are allocated in the heap of Java memory. So, there is a heap memory in Java where new whenever
you call a new and allocate object that is allocated in the heap also arrays are object in Java, so they are also
allocated in heap.
o Static members, class definitions, class metadata etc are stored in method area of the JVM which is
basically the permgen or the metaspace in modern Java versions like Java 8.
o Garbage collection is carried out by a daemon thread called garbage collector.
o We can’t force GC to happen using (System.gc()).
o When new allocation can’t happens due to a full heap you end up with a Java.lang.OutOfMemoryError
heap space . so, indicating you are no longer able to use heap anymore because it's full and that is a time
when you will probably start looking for objects leaks or memory leaks in your program.
o

Garbage collection Involves-


Mark: starts from root node of your application(main), walks the object graph, marks objects that are reachable
as live.
Delete/sweep: delete unreachable objects
Compacting: compact the memory by moving around the objects and making the allocation contiguous then
fragmented.

- Mark:- Garbage collection basically involves 3 steps which is mark and sweep and compacting. So, mark is
basically a step where the garbage collector walks through the object graph which I talked about which is
basically will have a root node of your application. Suppose you have a class called application which got
invoked at the beginning and everything gets created from there so that is the root node and from that root
node you have references to some other objects and all of them refers to something else so it's like a big graph
in memory. So, the garbage collector walks that graph and visits each node and marks whichever object is
reachable as reachable and whichever object is not reachable it just leaves alone and moves forward.
-Sweep:- So next step is deleting or sweeping so as a name indicates is the step where things are cleared off.
So, whichever is marked as reachable is not touched and whichever is not reachable the garbage collector
thread would just clean them or sweep them off from the heap and thus reclaims the memory but then comes
the step of compacting.
-Compacting:- So compacting is the process where you try to arrange everything in order. So, suppose we have
heap here so let's assume heap like a big grid of something and from in the grid you could have unreachable
object here. So, you keep on cleaning them off then there are holes in the whole heap right. So, there are so
suppose you don’t have contiguous allocation suppose here allocation has happened here you have removed
something which is unreachable then again, some reachable objects. So, to avoid this fragmentation the
compaction is done. So, all the objects are arranged in order so that you know free memory is at the end of the
heap. So that is basically compaction and if you have used the disk defragment tool that comes with Windows
you would have seen a graphic representation of how the disk files and the disk blocks which are non-
contiguous how it makes contiguous. So, you would have seen that so it's similar to that the compacting step
and as you can imagine that's a time-taking step because it has to go through the entire heap and then arrange
to the allocated space accordingly. So we'll come to that details very shortly so let's proceed and see what are
the generations in Java heap.

Generational Collectors
So basically, Java garbage collectors are called generational collectors because it depends on the generation of
your objects meaning if the object is young or if the object is old or did the object survive how many cycles of
garbage collection and things like that. So, as you can see in this diagram the heap is divided into two spaces
one is young generation space and the other one is old or tenured generation space. So, the young generation as
you can see is the place where objects are created initially. So young generation as the name indicates is for
young objects where the new objects are created, and young generation is further divided into Eden space. Eden
is a place where new things are created actually whenever you call something like new say hash map for
example that hash map objects is created in the Eden space and it's called Eden because it's a reference to the
theory of Genesis in Bible where according to the books the life was first created in garden of Eden so they just
used that name so it's called Eden space where new objects are created. So, there are then survivor space that
means suppose objects are allocated in the Eden space and the Eden space becomes full that means whenever
you call something like new hash map next time you don't have any more Eden space to create that hash map.
So that is the time small garbage collection kicks in and cleans up the Eden space of all unreachable objects and
all reachable object it moves on to the survivor space indicating it survived a garbage collection. So, then Eden
becomes free and again you can happily allocate new objects there. So, there are other purpose of why there are
two survivor spaces we will soon see that. So that is the division of young generation into three spaces.

Then you have old generation which holds objects that survives for a long time are promoted into old
generation. Suppose you created a cache in your application which is supposed to stay there for the entire
applications life. So suppose initially when you created your cache it's created in the Eden space and then it's
moved to survivor space and after a few generations of garbage collection suppose it survives a lot of cycles of
garbage collection that cache object will be moved to old generation where it stays and if it is never unreachable
it just stays forever and if it ever becomes unreachable it gets collected by a major garbage collection which
actually runs garbage collection steps all throughout the heap.
So, in this slide we saw a couple of very important points
o one is the division of heap into young and old generation and another one is
o minor garbage collections that run in the young generation and major garbage collection that runs across the
heap.
o at the same time, you should be aware that any steps of garbage collection minor or major they are called
stop the world garbage collection. So both are stop the world only thing is that minor is running on a very
small a short amount of memory and so it's not that you know intrusive you won't feel that the application is
stopping or something but when the major garbage collection kicks in it has to run from the entire heap
from one end to the other and do the mark sweep and compacting of the whole objects so that would really
cause a pause in your application for about seconds which would be really undesirable. So those are some
points that we should keep in our mind from this slide.
 So in this animation what I'm going to show is how the Eden space minor garbage collections happen and also you
should be aware that this slide is only showing the young generation it's not showing the old generation okay so here I
have the Eden space where objects are created and here I have the survivor from space and survivor to space so as
the application your application runs new objects get allocated in the Eden space and when the application runs there
are objects that become unreachable I'm marking them as Gray here and then now the Eden space is kind of full so at
this point when your application tries to create another objects and JVM tries to allocate something on the Eden the
allocation fails and that actually causes one minor GC to run and when minor GC runs at the end of it it has marked all
the live objects as reachable and those are moved into the survivor space.

 So, when they are moved into survivor space the unreachable objects are sweeped and cleaned up and we are good.
So this slide indicates the after first cycle of garbage collection what just happened you have you know all the objects
that survived one cycle of garbage collection in the survivor space and they are all have a counter it says okay it
survived one cycle of garbage collection now again the application goes and allocates objects in the heap and along
the way some things in the survivor space becomes unreachable and more objects are allocated some objects are
again becoming unreachable and stuff like that and at this point the heap is the Eden of the heap is full and there are
some unreachable objects here and there are new objects reachable objects here reachable out objects are still here
so at this point JVM tries to allocate yet another object and it fails and

 when the allocation fails it triggers yet another minor GC and at the end of that minor GC all the reachable objects are
marked as still as reachable across the Eden and survivor and then they are all moved to the survivor 2 as you can see
they are moved to the survivor space 2 and objects from survivor 1 is also moved into survivor 2 okay so this is how
that movement happens and now clean-up of these unreachable objects are done and all the reachable objects are
now in survivor 2 like this so this indicates okay there are these objects that survive two cycles of garbage collection
and these objects that survives one cycle of garbage collection
 so you might wonder why there is this multiple survivor space in heap so the reason is because to avoid another run
of compacting step so as you can see when the movement happens they are arranged in sequential order like a
contiguous order so this actually avoids the need to run another compacting step that will be expensive but instead
since you have to anyway move around the objects you are just moving it away and ordering it one after other and
avoiding the compacting step so that is the purpose of the survivor spaces and now let's see what happens in the heap
again new objects are created in the heap some things are becoming unreachable these are again here these are
becoming unreachable and then you keep JVM keeps on allocating your objects whenever needed and there are a lot
of unreachable objects now in Eden as well as the survivor and the Eden is sort of full now and now you try to allocate
one more objects and that allocation fails and at this point one more minor GC gets triggered and as a result all the
reachable objects are moved to survivor 1 so things are now moving back to survivor 1 from survivor 2 as you can see
so at the end of this all the unreachable objects are cleaned up
 so there are some things that you should be aware of that you know the minor GC is very short because it's running
quickly over the Eden space and the survivor space and at the end of that cycle objects are moved into the survivor
space from one survivor to another and then from there back to the previous survivor and this you know reordering
continues until a threshold number say 16 let's take 16 as the example and at the end of that threshold what will
happen is whatever is survived for example see here the counter has incremented indicating these objects survived
one cycle of garbage collection this survived two cycles of garbage collection and this survived three collections of
three cycles of garbage collection so

 when the threshold is hit saying okay if any object is has survived say 16 cycles of garbage collections they are
promoted to the next generation which is old generation indicating okay these are objects that are really not going
away they are going to stay here for a while so they are moved to old generation as you can see in this diagram so
that is based on a max tenuring threshold and all the objects that are living long in survivor or Eden they are moved
out into old generation and there is some breathing space again back in the young generation so those are the basic
functionality of garbage collector and how it is implemented

 so what happens when old generation gets full so there is this garbage collect thread that keeps on watching old
generation sees oh my god my old generation is almost full now I'm soon going to be in trouble so at that point of
time the major garbage collection kicks in which goes over all the generations and performs mark sweep and
compacting which is you know three of these steps it has to perform and it has to perform across the heap suppose
your heap size is say 8 GB or 16 GB it has run across the whole 8 GB allocated for JVM and hence it can be a very time-
consuming operation causing your application to halt literally okay so as you can see a lot of minor garbage
collections runs in the background on the young generation which are quick so it doesn't appear to be really pausing
your application but the major generation which is going to run through the entire heap would cause your application
to pause.

Let's talk about performance with relation to garbage collection so in performance we have to be aware of two terms okay
so one is responsiveness or latency and the second one is throughput.

Performance

- Responsiveness/Latency

How quickly an application response with a requested piece of data. Examples:


- How quickly a desktop UI responds to an event
- How fast a website returns a page
- How fast a database query is returned
- For applications that focus on responsiveness, large pause times are not acceptable. The focus is on
responding in short periods of time.

- Throughput

Throughput focus on maximizing the amount of work by an application in a specific period of time. Example of how
throughput might be measured include:
- The number of transactions completed in a given time.
- The number of jobs that a batch program can complete in an hour.
- The number of database queries that can be completed in an hour.
- High pause times are acceptable for applications that focus on throughput. since high throughput
applications focus on benchmarks over longer periods of time, quick response time is not consideration.

Types of Garbage Collectors-

1. A serial Collector
 A very Basic Garbage Collector that runs in a Single Thread.
 you know the that means your application will be running suddenly it's paused and a single
thread of garbage collection of mark sweep and compacting runs again your application runs
again paused and a single thread of your mark sweep and compacting is done so that is a
serial collector.
2. A Concurrent Collector
 A thread that performs garbage collection along with the application so that means as the
application runs this concurrent thread of garbage collection also runs.
 Doesn’t wait for the old generation to be full. (It does not wait for the old generation to be full so it
keeps on running and whenever it can it can do certain sweeping compacting happens in parallel with the
application so that is why it is called the concurrent collector)
 Stops the world only during mark/re-mark.
3. A Parallel Collector
 Uses multiple CPUs to perform GC
 Multiple Threads do mark/sweep etc.
 Doesn’t kick in until heap is full or near full.
 “stop-the-world” when it runs.

When to use Concurrent Collector Vs Parallel Collector

Use Concurrent Collectors (CMS) When:


o There is more memory.
o There is high number of CPUs.
o Applications demands short pauses.
o Concurrent collector or Concurrent mark sweep (CMS) in Java is known as low latency
collector which is one of the most favoured garbage collectors for most of the application
most of the web applications most of the financial applications, they use the concurrent
mark sweep garbage collector

Use Parallel Collectors When:


o There is less memory.
o There is lesser number of CPUs.
o Applications demands high throughput and can with stand pauses.

4. G1 Garbage Collector (Garbage-first)


implementing g1 garbage collector is-
o As of modern Java implementation 7 onwards 1.7 updated for G1 garbage collector was
implemented so g1 means garbage first so, what was the need for basically to make it more
predictable in terms of the GC process you could mention in the command line how much time
you would like the GC to pause your VM and low amount of fragmentation or pauses.
o It mixes both parallelism as well as the concurrent collection
o It results in better heap utilization so what it does is basically the g1 garbage collection
mechanism basically divides your heap into small regions of memory and each of this region can
be a Eden space, it can be a survivor space it can be a tenured space and whenever whichever
region has you know a lot of unreachable objects more garbage wherever there is more garbage
that area quickly gets collected by the thread and so that is why it's called garbage first collector.
o So, it's kind of concurrent as well as parallel at the same time
o It's working on short pieces of memory regions so it's going to be faster and that way it can kind
of take care of having minimal amount of pauses or stick to what you want to be the pause to be
so that is the g1 or garbage first garbage collector in Java 7 and 8.
o More predictable/tannable GC pauses.
o Papalism and concurrency together.
o Better Heap Utilization.
Can you please explain some scenarios where you have faced memory leak, OR scenarios where
memory leak could happen in java?

Answer.

1) Static variables/ fields are not garbage collected and can cause memory leak in java >

Static variables are only garbage collected when the class loader which has loaded the class in which static field
is there is garbage collected.
So, be cautious as these static variables can create a memory leak in java.

2) Thread Local Variables can cause memory leak in java >


A thread local variable is member field in the Thread class. Such thread local variable can be used to hold the
thread state.
But thread local variable aren’t garbage collector till thread is alive.

3) Memory leak while using Autoboxing and unboxing in java >


For addition of numbers we must prefer to use primitive data type, not the Object wrapper class. Addition of
numbers using Integers turns out into very costly operation in terms of performance, boxing/unboxing and
unnecessary object formations.
Just imagine a situation where 1000000’s... of number are being added using Integer, it will literally explode
our heap memory and boxing/unboxing operations will have adverse effect on performance.

4) Avoid memory leak using Weak HashMap in java


An entry in a Weak HashMap will be automatically removed by garbage collector when its key is no longer in
ordinary use. So, using Weak HashMap in place of HashMap can help us in avoiding memory leaks.

5) Using custom key in map without Overriding equals () and hashCode() method can cause memory leak >
If custom key is used and equals() and hashCode() method are not overridden then, key will not be retrieved
by using get() method.
Because get () method internally calls equals () and hashCode () method for retrieving keys.
So, these keys will neither be used nor be garbage collected, so it’s a clear case of memory leak.

So, to avoid memory leak while using custom key you must always Override equals () and hashCode() method
Learn how you can use custom key (Employee object) in custom HashMap Custom implementation - put, get,
remove So, to avoid memory leak you must try use String, Integer, Long, Double, Float, Short and any other
wrapper class as key in HashMap.

6) Close JDBC Statement, PreparedStatement, CallableStatement , ResultSet and Connections in java to


avoid memory leaks >
You must ensure that you close all the JDBC Statement, PreparedStatement, CallableStatement , ResultSet
and Connections in java to avoid memory leaks. You must always close all the above mentioned objects in
finally block in java because finally block is always executed irrespective of exception is thrown or not by java
code.

7) Memory leaks can also be caused by native methods in java > Memory allocated through native methods
can cause some serious memory leak.
8) Memory leak in web applications in java
Unused Objects stored in application scope are memory leak because they are not collected until web
application is stopped.

Is there any difference between creating string with and without new operator?
When String is created without new operator, it will be created in string pool.

When String is created using new operator, it will force JVM to create new string in heap (not in string pool).

Let’s discuss step-by-step what will happen when below 5 statements will be executed >
String s1 = "abc";
String s2 = new String("abc");
String s3 = "abc";
String s4 = new String("abc");
String s5 = new String("abc").intern();

String s1 = "abc";
No string with “abc” is there in pool, so JVM will create string in string pool and s1 will be a reference variable which will
refer to it.

String s2 = new String("abc");


string is created using new operator, it will force JVM to create new string in heap (not in string pool).

String s3 = "abc";
string with “abc” is there in pool, so s3 will be a reference variable which will refer to “abc” in string pool.

String s4 = new String("abc");


string is created using new operator, it will force JVM to create new string in heap (not in string pool).

String s5 = new String("abc").intern();


string is created using new operator but intern method has been invoked on it, so s5 will be a reference variable which will
refer to “abc” in string pool.

What is significance of final in java?

1. Final memberVariable/instanceVariable of class must be initialized at time of declaration, once initialized final
memberVariable cannot be assigned a new value.

2. Final method cannot be overridden, any attempt to do so will cause compilation error.

Runtime polymorphism is not applicable on final methods because they cannot be overridden.

3. Final class cannot be extended, any attempt to do so will cause compilation error.

Final keyword can be applied to following in java >


 variable,
 method and
 class.

1) Final variable - once initialized final memberVariable cannot be assigned a new value in java

final can be applied to following variable types in java -


 final memberVariable/instanceVariable
 final local variable
 final static variable

Final memberVariable/instanceVariable of class must be initialized at time of declaration, once initialized final
memberVariable cannot be assigned a new value in java.

class FinalTest {
final int x=1; //final memberVariable/instanceVariable
}

If final memberVariable is not declared at time of declaration we will face compilation error= “The blank final field x may
not have been initialized”’.
If final memberVariable is assigned a new value we will face compilation error=”The final field FinalTest.x cannot be
assigned ”.

If constructor is defined then final memberVariable can be initialized in constructor but once initialized cannot be assigned a
new value.
class FinalTest {
final int x; //final memberVariable/instanceVariable
FinalTest() {
x = 1; //final memberVariable can be initialized in constructor.
}
}

Final local variable can be left uninitialized at time of declaration and can be initialized later, but once initialized cannot be
assigned a new value in java.
class FinalTest {
void method(){
final int x; //final variable uninitialized at time of declaration
x=1;
}
}

Final static variable of class must be initialized at time of declaration or can be initialized in static block, once initialized
final static variable cannot be assigned a new value.

If static block is defined then final static variable can be initialized in static block, once initialized final static variable cannot
be assigned a new value in java.
class FinalTest {
final static int x; //final static variable
static{ //static block
x=1;
}
}

So, in short using final with variable means that it cannot be assigned a new value in java.

2) Final method - final method cannot be inherited in java.

Final method cannot be overridden, any attempt to do so will cause compilation error.

Runtime polymorphism is not applicable on final methods because they cannot be inherited.
So, in short using final with method means that it cannot be inherited in java.

3) Final class - final class cannot be extended in java.


Final class cannot be extended, any attempt to do so will cause compilation error.

So, in short using final with class means that it cannot be extended in java.

20 salient features of final keyword in java >

1. Final is a keyword in java.

2. Final keyword can be applied to variable, method and class in java.

3. Final memberVariable/instanceVariable of class must be initialized at time of declaration, once initialized final
memberVariable cannot be assigned a new value.

class FinalTest {
final int x=1; //memberVariable/instanceVariable
}

4. If final memberVariable is not declared at time of declaration we will face compilation error= “The blank final
field x may not have been initialized”’.

5. If final memberVariable is assigned a new value we will face compilation error=”The final field FinalTest.x cannot
be assigned ”.

6. If constructor is defined then final memberVariable can be initialized in constructor but once initialized cannot be
assigned a new value.

class FinalTest {
final int x; //memberVariable/instanceVariable
FinalTest() {
x = 1; //final memberVariable can be initialized in constructor.
}
}

Best practice : We must initialize member variables of class in constructor.

7. Final local variable can be left uninitialized at time of declaration and can be initialized later, but once initialized
cannot be assigned a new value.

class FinalTest {
void method(){
final int x; //uninitialized at time of declaration
x=1;
}
}

8. Final static variable of class must be initialized at time of declaration or can be initialized in static block, once
initialized final static variable cannot be assigned a new value in java.

9. Final static member variables of class are called constants in java.

variables in interface are public, static and final by default. Interface variables are also known as constants.

10. If static block is defined then final static variable can be initialized in static block, once initialized final static
variable cannot be assigned a new value in java.

class FinalTest {
final static int x; //static variable
static{ //static block
x=1;
}
}

11. Final method cannot be overridden, any attempt to do so will cause compilation error in java.

Runtime polymorphism is not applicable on final methods because they cannot be overridden.

12. Final method are inherited in subclasses in java.

class Superclass {
final void superclassFinalMethod(){
System.out.println("in Superclass final method");
}
}
class Subclass extends Superclass{
void subclassmethod(){
System.out.println("in sub class method");
}
}
public class FinalTest {
public static void main(String[] args) {
Subclass obj=new Subclass();
obj.superclassFinalMethod();
}
}
/*OUTPUT
in Superclass final method
*/

superclassFinalMethod method of Superclass was inherited in Subclass.

13. Final class cannot be extended, any attempt to do so will cause compilation error in java.
14. Constructor of a class can never be final in java - because they are not inherited neither overridable.
Only public, protected & private are permitted modifiers with constructor.
,any attempt to make constructor final will cause compilation error=”Illegal modifier for the constructor in type FinalTest;
only public, protected & private are permitted” in java.

15. There is nothing like final object in java - if final reference variable refers to object in java than it does not mean
that Object is final, it simply means that reference variable cannot refer to another object in java.
16. final list does not means that - value cannot be added to it or removed from list.
final list means reference cannot refer to any new ArrayList, any attempt to do so will cause compilation error in java.

17. If parameter is final its value cannot be changed, any attempt to do so will cause compilation error in java.

18. Final class can never be abstract, because final class cannot be extended and abstract class is meant for
extending
any attempt to do so will cause compilation error in java.

19. declaring variable, class or method as final improves performance, because JVM caches them. JVM caches them
because -
a. final variable cannot be changed in java,
b. Runtime polymorphism is not applicable on final methods because they cannot be overridden in java.
c. final classes cannot be inherited in java.

20. As per java naming conventions final variable must be written in UPPERCASE because they are considered as
constants in java.

final int VARIABLE=1;

21. Only final local variable can be used inside an inner class defined in a method.
Though non-final member variable can be used inside an inner class defined in a method.
class MyClass{}
class MainClass {
int memberVar=0; //member variable
void m(){
final int localVar=0; //final local variable
MyClass myClass=new MyClass(){
void m(){
System.out.println(localVar);
System.out.println(memberVar);
}
};
}
}

Using non-final local variable inside an inner class will produce compilation error =”Cannot refer to a non-final variable
localVar inside an inner class defined in a different method” in java.

Anonymous Inner Class


An inner class declared without a class name is known as an anonymous inner class. In case of anonymous
inner classes, we declare and instantiate them at the same time. Generally, they are used whenever you need to
override the method of a class or an interface. The syntax of an anonymous inner class is as follows −
Syntax

AnonymousInner an_inner = new AnonymousInner() {


public void my_method() {
........
........
}
};

Can we use custom object as key in HashMap? If yes then how?

For using object as Key in HashMap, we must implements equals and hashcode method.
Classes must be made immutable classes.

By overriding equals() and hashCode() method we could >


 use custom object as key in Map ( HashMap, Hashtable, TreeMap or LinkedHashMap etc..), or
 use store custom object in Set (HashSet, CopyOnWriteArraySet, LinkedHashSet or TreeSet).

What we should do to override equals() and hashCode() >


1) Check whether obj is null or not.
if(obj==null) //If obj is null, return without comparing obj & Employee class.
2) check whether obj is instance of Employee class or not.
if(this.getClass()!=obj.getClass()) //identifies whether obj is instance of Employee class or not.
3) Then, type cast obj into employee instance.
Employee emp=(Employee)obj; //type cast obj into employee instance.
@Override
public boolean equals(Object obj){
if(obj==null)
return false;
if(this.getClass()!=obj.getClass())
return false;
Employee emp=(Employee)obj;
return (emp.id==this.id || emp.id.equals(this.id))
&& (emp.name==this.name || emp.name.equals(this.name));
}

@Override
public int hashCode(){
int hash=(this.id==null ? 0: this.id.hashCode() ) +
(this.name==null ? 0: this.name.hashCode() );
return hash;
}

Let’s say in an organisation there exists a employee with id=1 and name=’sam’ and some data is stored corresponding to
him, but if modifications have to be made in data, previous data must be overridden.

Full Program/SouceCode >


import java.util.HashMap;
class Employee {
private Integer id;
private String name;
public Employee(Integer id, String name) { // constructor
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Employee[id=" + id + ", name=" + name + "] ";
}
@Override
public boolean equals(Object obj){
if(obj==null) //If obj is null, return without comparing obj & Employee class.
return false;
if(this.getClass()!=obj.getClass()) //identifies whether obj is instance of Employee class or not.
return false;
Employee emp=(Employee)obj; //type cast obj into employee instance.
return (emp.id==this.id || emp.id.equals(this.id))
&& (emp.name==this.name || emp.name.equals(this.name));
}

@Override
public int hashCode(){
int hash=(this.id==null ? 0: this.id.hashCode() ) +
(this.name==null ? 0: this.name.hashCode() );
return hash;
}
}
public class EmployeeOverride {
public static void main(String...a){
HashMap<Employee, String> hm=new HashMap<Employee, String>();
hm.put(new Employee(1,"sam"), "employee1 data");
hm.put(new Employee(2,"amy"), "employee2 data");
System.out.println("HashMap's data> "+hm);
System.out.println(hm.get(new Employee(1,"sam")));
hm.put(new Employee(1,"sam"), "employee1 data OVERRIDDEN");
System.out.println("\nAgain display HashMap after overriding data "+
"of Employee with id=1 and name=’sam’\n");
System.out.println("HashMap's data> "+hm);
System.out.println(hm.get(new Employee(1,"sam")));

}
}
/*OUTPUT
HashMap's data> {Employee[id=1, name=sam] =employee1 data, Employee[id=2, name=amy] =employee2 data}
employee1 data
Again display HashMap after overriding data of Employee with id=1 and name=’sam’
HashMap's data> {Employee[id=1, name=sam] =employee1 data OVERRIDDEN, Employee[id=2, name=amy]
=employee2 data}
employee1 data OVERRIDDEN
*/
If we note output >
Earlier, value corresponding to Employee with id=1 and name=’sam’ was employee1 data
Later, value corresponding to Employee with id=1 and name=’sam’ was employee1 data OVERRIDDEN

What is Immutable class?


Any change made to object of immutable class produces new object.
Example- String is Immutable class in java, any changes made to Sting object produces new String object.

Creating Immutable class >

1) Final class - Make class final so that it cannot be inherited

2) private member variable -> Making member variables private ensures that fields cannot be accessed outside class.

3) final member variable -> Make member variables final so that they can be assigned only once.

4) Constructor -> Initialize all fields in constructor.


assign all mutable member variable using new keyword.

5) Don't provide setter methods in class/ provide only getter methods.

6) object of immutable class - Any change made to object of immutable class produces new object.
object of mutable class - Any change made to object of mutable class doesn't produces new object.
- Integer, String are immutable class,
any changes made to object of these classes produces new object.
so return reference variable of Integer.
- HashMap is mutable class,
any changes made to HashMap object won't produce new HashMap object.
so return copy/clone of object, not reference variable of HashMap.*/

Program to create Immutable class>


import java.util.HashMap;
/** ImmutableClass
* 1) Final class - Make class final so that it cannot be inherited
*/
final class ImmutableClass{

/**
* 2) private member variable -> Making fields private ensures that fields
cannot be accessed outside class.
* 3) final member variable -> Make field final
so that they can be assigned only once.
*/
private final Integer id; //Immutable member variable
private final String name; //Immutable member variable
private final HashMap<Integer,String> map; //mutable member variable
/** 4) Constructor -> Initialize all fields in constructor.
* assign all mutable member variable using new keyword.
*/
public ImmutableClass(Integer id, String name, HashMap<Integer,String> map){
this.id=id;
this.name=name;

//assign all mutable member variable using new keyword.


this.map=new HashMap<Integer, String>(map);
}

/* getter method for id.*/


public Integer getId() {
/** 5a) Integer is immutable class,
* any changes made to Integer object produces new Integer object.
* so return reference variable of Integer.
*/
return id;
}
/* getter method for name.*/
public String getName() {
/** 5b) String is immutable class,
* any changes made to Sting object produces new String object.
* so return reference variable of String.
*/
return name;
}
/* Method returns clone of HashMap. */
public HashMap<Integer, String> getMap() {
/** 5c) HashMap is mutable class,
* any changes made to HashMap object won't produce new HashMap object.
* so return copy/clone of object, not reference variable of HashMap.*/
return (HashMap<Integer, String>) map.clone();
}

/** 6) Don't provide setter methods in class */


}
/*
* Main class for testing ImmutableClass
*/
public class ImmutableClassTest{
public static void main(String[] args) {

Integer localId=new Integer(1); //local

String localName=new String("ankit"); //local

HashMap<Integer, String> localMap = new HashMap<Integer,String>(); //local


localMap.put(11, "audi");

ImmutableClass immutableClass = new ImmutableClass(localId, localName, localMap);

System.out.println("----Display ImmutableClass members before changing----");


System.out.println(immutableClass.getName()); // "ankit"
System.out.println(immutableClass.getId()); // 1
System.out.println(immutableClass.getMap()); //{11=audi}
//Comparing ImmutableClass members with local before changing
System.out.println(localName==immutableClass.getName()); //true
System.out.println(localId==immutableClass.getId()); //true
System.out.println(localMap == immutableClass.getMap()); //false

//change local
localId = new Integer(2);
localName = new String("mittal");
localMap.put(12, "ferarri");

System.out.println("\n----Display ImmutableClass members after changing----");


System.out.println(immutableClass.getName()); // "ankit"
System.out.println(immutableClass.getId()); // 1
System.out.println(immutableClass.getMap()); //{11=audi}
//Comparing ImmutableClass members with local after changing
System.out.println(localName==immutableClass.getName()); //false
System.out.println(localId==immutableClass.getId()); //false
System.out.println(localMap == immutableClass.getMap()); //false
}
}
/*OUTPUT
----Display ImmutableClass members before changing----
ankit
1
{11=audi}
true
true
false
----Display ImmutableClass members after changing----
ankit
1
{11=audi}
false
false
false
*/

Should we make the class and methods both final?


No, If we have made class final then there is no need to make methods final, because final class cannot be extended and
hence methods cannot be overridden.

Example of immutable classes in java>


 String
 Integer (Wrapper class)
 Double (Wrapper class)
 Long (Wrapper class)
 Short (Wrapper class)
 Byte (Wrapper class)
 And all other Wrapper classes.

Advantages of using Immutable class >


 Thread safe - Immutable classes are thread safe, they will never create race condition.
 Key in HashMap - Immutable classes are can be used as key in Map (HashMap etc.)
 HashCode is cached - JVM caches the HashCode of Immutable classes used in application. JVM need not to
calculate hashcode again. Hence, performance of application is improved significantly.
 If Immutable class throws Exception - If Immutable class throws Exception, they are never left in undesirable
state.

What classes should i prefer to use a key in HashMap? (Important)

This question will check your in depth knowledge of Java’s Collection Api’s. we should prefer String, Integer, Long,
Double, Float, Short and any other wrapper class. Reason behind using them as a key is that they override equals() and
hashCode() method, we need not to write any explicit code for overriding equals() and hashCode() method.

Let’s use Integer class as key in HashMap.

import java.util.HashMap;
import java.util.Map;
public class StringInMap {
public static void main(String...a){

//HashMap's key=Integer class (Integer’s api has already overridden hashCode() and equals() method for us )
Map<Integer, String> hm=new HashMap<Integer, String>();
hm.put(1, "data");
hm.put(1, "data OVERRIDDEN");
System.out.println(hm.get(1));

}
}
/*OUTPUT
data OVERRIDDEN
*/
If, we note above program, what we will see is we didn’t override equals() and hashCode() method, but still we were able to
store data in HashMap, override data and retrieve data using get method.
>Let’s check in Integer’s API, how Integer class has overridden equals() and hashCode() method :

public int hashCode() {


return value;
}
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value ==
((Integer)obj).intValue();
}
return false;
}

Can overriding of hashcode() method cause any performance issues?


Improper implementation of hashCode() can cause performance issues, because in that most of the key-value pairs will be
stored on same bucket location and unnecessary time will be consumed while fetching value corresponding to key.

Why do we need to override equals and hashcode method?


Answer. Equals() and hashCode() are methods of java.lang.Object
It’s important to override equals() and hashCode() method of class if we want to use class as key in HashMap.
If we don’t override equals() and hashCode() method we will be able to put object, but we won’t be able to retrieve object.

Before understanding the concept of overriding equals() and hashCode() method, we must understand what is bucket,
Entry, and Entry.next

Bucket is ArrayList of Entry.


Entry is LinkedList which contains information about key, value and next.
Entry.next points to next Entry in LinkedList.
>Why to override hashcode method?
It helps in finding bucket location, where entry(with key-value pair) will be stored .
Entry (of type LinkedList) is stored in bucket (ArrayList).

If, hashCode() method is overridden properly, we will find bucket location using hashCode() method, we will obtain
Entry on that bucket location, then iterate over each and every Entry (by calling Entry.next) and check whether new and
existing keys are equal or not. If keys are equal replace key-value in Entry with new one, else call Entry.next But, now the
question comes how to check whether two keys are equal or not. So, it’s time to implement equals() method.

If, hashcode method is not overridden for same key every time hashCode() method is called it might produce different
hashcode, there might happen 2 cases i.e. when put and get method are called.
Case 1 : when put() method is called-
There might be possibility that same Entry (with key-value pair) will get stored at multiple locations in bucket.
Conclusion> key- value pair may get stored multiple times in HashMap.
Case 2 : when get() method is called-
As there is possibility that hashCode() method might return different hashcode & rather than searching on bucket location
where Entry(with key) exists we might be searching for key on some other bucket location.
Conclusion> key existed in HashMap, but still we were not able to locate the bucket location in which it was stored.

>Why to override equals method?


Once we have located bucket location in which our Entry (with key-value pair) will be stored, Equals method helps us in
finding whether new and existing keys are equal or not.

If equals method is not overridden - though we will be able to find out correct bucket location if hashCode() method is
overridden correctly, but still if equals method is not overridden, there might happen 2 cases i.e. when put and get method
are called.
Case 1 : when put() method is called-
we might end up storing new Entry (with new key-value pair) multiple times on same bucket location (because of absence of
equals method, we don’t have any way of comparing key’s),
In this case, even if keys are equal, we will keep on calling Entry.next until we reach last Entry on that bucket location and
ultimately we will end up storing new Entry (with new key) again in same bucket location.
Conclusion> key- value pair stored multiple times in HashMap.
Case 2 : when get() method is called-
we won’t be able to compare two keys (new key with existing Entry.key) and we will call Entry.next and again we won’t
be able to compare two keys and ultimately when Entry.next is null - we will return false.
Conclusion> key existed in HashMap, but still we were not able to retrieve it.
So, it’s important to override equals method to check equality of two keys.

If two objects have same hashcode, are they always equal?


Answer. No, It’s not necessary that object’s having same hashcode are always equal. Because same hashcode means object
are stored on same bucket location, as key/object in bucket is stored in Entry(Linked List), key/object’s might be stored on
Entry.next (i.e. on some different entry)

If two objects equals() method return true, do objects always have same hashcode?
Answer. Yes, two objects can return true only if they are stored on same bucket location.
First, hashCode() method must have returned same hashcode for both objects, then on that bucket location’s Entry
key.equals() is called, which returns true to confirm objects/keys are equal.
So, if object’s equals return true, they always have same hashcode.

Can two unequal objects have same hashcode?


Answer. Yes, two unequal objects can have same hashcode.

What is difference between using instanceOf operator and getClass() in equals method?
Answer. If we use instanceOf it will return true for comparing current class with its subclass as well,
but getClass() will return true only if exactly same class is compared. Comparison with any subclass will return false.

How we can implement HashMap for using Integer as key? (Important)


Answer. Here Interviewer tends to check your knowledge of overriding equals and hashCode method, and also how Api’s
use Integer internally as key in HashMap.
Let’s understand in detail how Integer is used as key in Hashmap.
Initially, we have bucket of capacity=4. (all indexes of bucket i.e. 0,1,2,3 are pointing to null).
Note: Initial capacity provided by Java Api is different.

Let’s put first key-value pair in HashMap-


Key=21, value=12

newEntry Object will be formed like this >


We will calculate hash by using our hash(K key) method - in this case it returns
key/capacity= 21%4= 1.
So, 1 will be the index of bucket on which newEntry object will be stored.
We will go to 1st index as it is pointing to null we will put our newEntry object there.

At completion of this step, our HashMap will look like this-

Interviewers sometimes tend to confuse interviewees by framing different question by overriding either of equals() or
hashCode() method. Interviewers aims to check in depth knowledge of interviewees that how many buckets are formed,
what is sizeOf HashMap after each experiment and get() method returns object or not (Important).

How many buckets will be there and what will be size of HashMap?

package p1;
import java.util.HashMap;
class Employee {

private String name;

public Employee(String name) { // constructor


this.name = name;
}
//no hashCode() method
//no equals() method

@Override
public String toString() {
return "Employee[ name=" + name + "] ";
}
}
public class Program1 {
public static void main(String...a){

HashMap<Employee, String> hm=new HashMap<Employee, String>();


hm.put(new Employee("a"), "emp1");
hm.put(new Employee("b"), "emp2");
hm.put(new Employee("a"), "emp1 OVERRIDDEN");

System.out.println("HashMap's data> "+hm);


System.out.println("HashMap's size> "+hm.size());
System.out.println(hm.get(new Employee("a")));

}
}
Answer.
/*OUTPUT
HashMap's data> {Employee[ name=a] =emp1 OVERRIDDEN, Employee[ name=a] =emp1, Employee[ name=b] =emp2}
HashMap's size> 3
null
*/
Buckets= As hashCode() method is not there, hashcode generated for 3 objects will be different and we will end up using 3
buckets.
Size= As equals() method is not their, size will be 3.
get()=we won’t be able to get object.

How many buckets will be there and what will be size of HashMap?
package p2;
import java.util.HashMap;
class Employee {

private String name;

public Employee(String name) { // constructor


this.name = name;
}

@Override
public int hashCode(){
return (this.name==null ? 0: this.name.hashCode() );
}
@Override
public boolean equals(Object obj){
Employee emp=(Employee)obj;
return (emp.name==this.name || emp.name.equals(this.name));
}
@Override
public String toString() {
return "Employee[ name=" + name + "] ";
}
}
public class Program2 {
public static void main(String...a){

HashMap<Employee, String> hm=new HashMap<Employee, String>();


hm.put(new Employee("a"), "emp1");
hm.put(new Employee("b"), "emp2");
hm.put(new Employee("a"), "emp1 OVERRIDDEN");

System.out.println("HashMap's data> "+hm);


System.out.println("HashMap's size> "+hm.size());
System.out.println(hm.get(new Employee("a")));

}
}
Answer.
/*OUTPUT
HashMap's data> {Employee[ name=b] =emp2, Employee[ name=a] =emp1 OVERRIDDEN}
HashMap's size> 2
emp1 OVERRIDDEN
*/
Buckets= As hashCode() method is overridden perfectly, 2 bucket locations will be used.
Size= As equals() method is their, size will be 2,
value corresponding to Employee with id=1 and name=’sam’ was employee1 data
& was overridden by value employee1 data OVERRIDDEN
get()=we will be able to get object.

How many buckets will be there and what will be size of HashMap?

package p3;
import java.util.HashMap;
class Employee {

private String name;

public Employee(String name) { // constructor


this.name = name;
}

@Override
public int hashCode(){
return 1;
}
@Override
public boolean equals(Object obj){
return true;
}
@Override
public String toString() {
return "Employee[ name=" + name + "] ";
}
}
public class Program3 {
public static void main(String...a){

HashMap<Employee, String> hm=new HashMap<Employee, String>();


hm.put(new Employee("a"), "emp1");
hm.put(new Employee("b"), "emp2");
hm.put(new Employee("a"), "emp1 OVERRIDDEN");

System.out.println("HashMap's data> "+hm);


System.out.println("HashMap's size> "+hm.size());
System.out.println(hm.get(new Employee("a")));
}
}
Answer.
/*OUTPUT
HashMap's data> {Employee[ name=a] =emp1 OVERRIDDEN}
HashMap's size> 1
emp1 OVERRIDDEN
*/
Buckets= As hashCode() method returns 1, only 1 bucket location will be used.
Size= As equals() method always returns true, size will be 1, all three employees will be stored on same bucket location in
one Entry (new Entry will keep on overriding previous Entry). We will always get last stored key-value pair only.
get()=we will be able to get object.

How many buckets will be there and what will be size of HashMap?

package p4;
import java.util.HashMap;
class Employee {

private String name;


public Employee(String name) { // constructor
this.name = name;
}
@Override
public int hashCode(){
return 1;
}
//no equals() method

@Override
public String toString() {
return "Employee[ name=" + name + "] ";
}
}
public class Program4 {
public static void main(String...a){

HashMap<Employee, String> hm=new HashMap<Employee, String>();


hm.put(new Employee("a"), "emp1");
hm.put(new Employee("b"), "emp2");
hm.put(new Employee("a"), "emp1 OVERRIDDEN");

System.out.println("HashMap's data> "+hm);


System.out.println("HashMap's size> "+hm.size());
System.out.println(hm.get(new Employee("a")));

}
}
Answer.
/*OUTPUT
HashMap's data> {Employee[ name=a] =emp1 OVERRIDDEN, Employee[ name=b] =emp2, Employee[ name=a] =emp1}
HashMap's size> 3
null
*/
Buckets= As hashCode() method returns 1, only 1 bucket location will be used.
Size= As equals() method doesn’t exist, size will be 3, all three employees will be stored on same bucket location but in
different Entry.
get()=we won’t be able to get object.
How many buckets will be there and what will be size of HashMap?

package p5;
import java.util.HashMap;
class Employee {

private String name;

public Employee(String name) { // constructor


this.name = name;
}

//no hashCode() method

@Override
public boolean equals(Object obj){
return true;
}
@Override
public String toString() {
return "Employee[ name=" + name + "] ";
}
}
public class Program5 {
public static void main(String...a){

HashMap<Employee, String> hm=new HashMap<Employee, String>();


hm.put(new Employee("a"), "emp1");
hm.put(new Employee("b"), "emp2");
hm.put(new Employee("a"), "emp1 OVERRIDDEN");

System.out.println("HashMap's data> "+hm);


System.out.println("HashMap's size> "+hm.size());
System.out.println(hm.get(new Employee("a")));

}
}

Answer.
/*OUTPUT
HashMap's data> {Employee[ name=b] =emp2, Employee[ name=a] =emp1 OVERRIDDEN, Employee[ name=a] =emp1}
HashMap's size> 3
null
*/
Buckets= As hashCode() method is not there, hashcode generated for 3 objects will be different and we will end up using 3
buckets.

Size= Though equals() method is their(but because of hashCode() method’s absence) which always returns true, we won’t
be able to locate correct bucket location for calling equals() method, so, size will be 3.
get()=we won’t be able to get object.

How many buckets will be there and what will be size of HashMap?

package p6;
import java.util.HashMap;
class Employee {

private String name;


public Employee(String name) { // constructor
this.name = name;
}

@Override
public int hashCode(){
return (this.name==null ? 0: this.name.hashCode() );
}
//no equals() method

@Override
public String toString() {
return "Employee[ name=" + name + "] ";
}
}
public class Program6 {
public static void main(String...a){

HashMap<Employee, String> hm=new HashMap<Employee, String>();


hm.put(new Employee("a"), "emp1");
hm.put(new Employee("b"), "emp2");
hm.put(new Employee("a"), "emp1 OVERRIDDEN");

System.out.println("HashMap's data> "+hm);


System.out.println("HashMap's size> "+hm.size());
System.out.println(hm.get(new Employee("a")));

}
}

Answer.
/*OUTPUT
HashMap's data> {Employee[ name=b] =emp2, Employee[ name=a] =emp1 OVERRIDDEN, Employee[ name=a] =emp1}
HashMap's size> 3
null
*/
Buckets= As hashCode() method is overridden perfectly, 2 bucket locations will be used.
Size= As equals() method is not their, size will be 3,
get()=we won’t be able to get object.

How many buckets will be there and what will be size of HashMap?

package p7;
import java.util.HashMap;
class Employee {

private String name;

public Employee(String name) { // constructor


this.name = name;
}

//no hashCode() method

@Override
public boolean equals(Object obj){
Employee emp=(Employee)obj;
return (emp.name==this.name || emp.name.equals(this.name));
}
@Override
public String toString() {
return "Employee[ name=" + name + "] ";
}
}

public class Program7 {


public static void main(String...a){

HashMap<Employee, String> hm=new HashMap<Employee, String>();


hm.put(new Employee("a"), "emp1");
hm.put(new Employee("b"), "emp2");
hm.put(new Employee("a"), "emp1 OVERRIDDEN");

System.out.println("HashMap's data> "+hm);


System.out.println("HashMap's size> "+hm.size());
System.out.println(hm.get(new Employee("a")));

}
}

Answer.
/*OUTPUT
HashMap's data> {Employee[ name=a] =emp1, Employee[ name=a] =emp1 OVERRIDDEN, Employee[ name=b] =emp2}
HashMap's size> 3
null
*/

Buckets= As hashCode() method is not there, hashcode generated for 3 objects will be different and we will end up using 3
buckets.
Size= Though equals() method is their(but because of hashCode() method’s absence), we won’t be able to locate correct
bucket location for calling equals() method, so, size will be 3.
get()=we won’t be able to get object.

How Integer is used as key in Hashmap in java


Let’s understand in detail how Integer is used as key in Hashmap.
Here I will try to explain how Integer is internally used as key in HashMap in Java Api.
Initially, we have bucket of capacity=4. (all indexes of bucket i.e. 0,1,2,3 are pointing to null).
Note: Initial capacity provided by Java Api is different.

Let’s put first key-value pair in HashMap-


Key=21, value=12

newEntry Object will be formed like this >


We will calculate hash by using our hash(K key) method - in this case it returns
key/capacity= 21%4= 1.
So, 1 will be the index of bucket on which newEntry object will be stored.
We will go to 1st index as it is pointing to null we will put our newEntry object there.
At completion of this step, our HashMap will look like this-
Let’s put second key-value pair in HashMap-
Key=25, value=121

newEntry Object will be formed like this >


We will calculate hash by using our hash(K key) method - in this case it returns
key/capacity= 25%4= 1.
So, 1 will be the index of bucket on which newEntry object will be stored.
We will go to 1st index, it contains entry with key=21, we will compare two keys(i.e. compare 21 with 25 by using equals
method), as two keys are different we check whether entry with key=21’s next is null or not, if next is null we will put
our newEntry object on next.
At completion of this step our HashMap will look like this-

Let’s put third key-value pair in HashMap-


Key=30, value=151

newEntry Object will be formed like this >

We will calculate hash by using our hash(K key) method - in this case it returns
key/capacity= 30%4= 2.
So, 2 will be the index of bucket on which newEntry object will be stored.
We will go to 2nd index as it is pointing to null we will put our newEntry object there.
At completion of this step, our HashMap will look like this-

Let’s put fourth key-value pair in HashMap-


Key=33, value=15

Entry Object will be formed like this >


We will calculate hash by using our hash(K key) method - in this case it returns
key/capacity= 33%4= 1,
So, 1 will be the index of bucket on which newEntry object will be stored.
We will go to 1st index -
>it contains entry with key=21, we will compare two keys (i.e. compare 21 with 33 by using equals method, as
two keys are different, proceed to next of entry with key=21 (proceed only if next is not null).
>now, next contains entry with key=25, we will compare two keys (i.e. compare 25 with 33 by using equals
method, as two keys are different, now next of entry with key=25 is pointing to null so we won’t proceed further, we
will put our newEntry object on next.
At completion of this step our HashMap will look like this-

What do you mean by fail-fast and fast-safe? What is


ConcurrentModificationException?
Answer.
Iterator returned by few Collection framework Classes are fail-fast, means any structural modification made to these classes
during iteration will throw ConcurrentModificationException.
Some important classes whose returned iterator is fail-fast >
 ArrayList
 LinkedList
 vector
 HashSet
Iterator returned by few Collection framework Classes are fail-safe, means any structural modification made to these classes
during iteration won’t throw any Exception.
Some important classes whose returned iterator is fail-safe >

 CopyOnWriteArrayList

 CopyOnWriteArraySet

 ConcurrentSkipListSet

What is fail-fast, fail-safe and ConcurrentModificationException in java ?


Iterator returned by few Collection framework Classes are fail-fast, means any structural modification made to these classes
during iteration will throw ConcurrentModificationException in java.

Iterator returned by few Collection framework Classes are fail-safe, means any structural modification made to these classes
during iteration won’t throw any Exception in java.

SECTION 1 (FAIL-FAST) :
Iterator returned by ArrayList are fail-fast, means any structural modification made to ArrayList during iteration will throw
ConcurrentModificationException in java.

Example/Program to show structural modification made to ArrayList during iteration will throw
ConcurrentModificationException in java.
public class ConcurrentModificationArrayListExample {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()){
String str = iterator.next();
System.out.print(str+" ");
if(str.equals("b"))
list.add("b2"); //will throw ConcurrentModificationException
}

System.out.println("\nAfter iteration list is : "+list);

}
}
/*OUTPUT
a b Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at
com.javaMadeSoEasy.ConcurrentModificationArrayListExample.main(ConcurrentModificationArrayListExample.java:2
0)
*/

Let’s discuss above program in detail


During execution of program ArrayList and Iterator returned by ArrayList maintains following variables >
Variables maintained by ArrayList -
> modCount =3
> size =3
Variables maintained by Iterator returned by ArrayList -
>expectedModCount =3
>Initially, cursor=0 > index of next element to return
means it is pointing to 1st element in list, i.e. on 0th index [increments every time when iterator.next() is called]
>Initially, lastRet= -1 > index of last element returned; -1 if no such
[increments every time when iterator.next() is called]

Every time iterator.next() is called it internally calls checkForComodification() to checks for any modification made to
list.
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}

if modCount is not equal to expectedModCount ConcurrentModificationException is thrown.


----
--------
What is modCount? What is structural modifications in java?
The number of times this list has been structurally modified. Any changes to size of list are called structural modifications in
java.

Which method cause structural modifications in java?


add() and remove() method changes size of list. Hence, cause structural modifications.
Every time any of these methods is called modCount is incremented by 1.

Additionally, you may also be interested in knowing what will happen if add() and remove() methods are called
subsequently in java?
Subsequent calls made to add() and remove() methods won’t avoid ConcurrentModificationException. Because in this case
modCount will be incremented twice by 1.

Which method does not cause structural modifications in java?


set() method does not changes size of list. Hence, does not cause any structural modifications.
Every time set() is called modCount remains unchanged.

How to use iterator.remove() in java?


We can remove elements from ArrayList using iterator’s remove method.
Every time iterator.remove() is called modCount remains unchanged.
But, if iterator.remove() is called before calling iterator.next() than IllegalStateException is thrown.

Below i have attached screenshot to show you variables maintained during runtime.
Note: Program was executed in debug mode. And screenshot was taken when we entered first time in while loop. Hence
value of cursor is 0 and lastRet’s is -1.

SECTION 2 (FAIL-SAFE) :
Iterator returned by CopyOnWriteArrayList are fail-safe, means any structural modification made to
CopyOnWriteArrayList during iteration won’t throw any Exception in java.

Example/ Program to show structural modification made to CopyOnWriteArrayList during iteration won’t throw any
Exception in java.
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class ConcurrentModificationCopyOnWriteArrayListExample {
public static void main(String[] args) {
List<String> list = new CopyOnWriteArrayList<String>();
list.add("a");
list.add("b");
list.add("c");

Iterator<String> iterator = list.iterator();


while(iterator.hasNext()){
String str = iterator.next();
System.out.print(str+" ");
if(str.equals("b"))
list.add("b2"); //No ConcurrentModificationException
}
System.out.println("\nAfter iteration list is : "+list);

}
}
/*OUTPUT
abc
After iteration list is : [a, b, c, b2]
*/

Let’s discuss above program in detail


During execution of program CopyOnWriteArrayList and Iterator returned by CopyOnWriteArrayList maintains
following variables >
Variables maintained by CopyOnWriteArrayList -
> lock > because CopyOnWriteArrayList is thread safe.
Variables maintained by Iterator returned by CopyOnWriteArrayList -
>snapshot, it is copy of CopyOnWriteArrayList (not the original CopyOnWriteArrayList)
>Initially, cursor=0 > index of next element to return
means it is pointing to 1st element in list, i.e. on 0th index [increments every time when iterator.next() is called]
It’s important to know that cursor is maintained on snapshot, rather than on list as in case of ArrayList (When iterating on
ArrayList, cursor is maintained on ArrayList, because no snapshot kind of variable exists there).
So why program did not throw ConcurrentModificationException?
Because when list.iterator() is called, a variable called snapshot is created which is copy of list (not the original list). Hence,
iteration does not care about structural modifications made to list.

Below i have attached screenshot to show you variables maintained during runtime.
Note: Program was executed in debug mode. And screenshot was taken when we entered first time in while loop. Hence
value of cursor is 0.

Some important classes whose returned iterator is fail-fast, means any structural modification made to these classes during
iteration will throw ConcurrentModificationException in java >
 ArrayList
 LinkedList
 vector
 HashSet
 EnumSet
 LinkedHashSet
 TreeSet

The iterators returned by the iterator() method of the collections returned by all three Map's “collection view methods" are
fail-fast >
map.keySet().iterator(), map.values().iterator(), map.entrySet().iterator()
 HashMap
 Hashtable
 LinkedHashMap
 TreeMap
 IdentityHashMap

Some important classes whose returned iterator is fail-safe, means any structural modification made to these classes during
iteration won’t throw any Exception in java >

 CopyOnWriteArrayList

 CopyOnWriteArraySet

 ConcurrentSkipListSet

The iterators returned by the iterator() method of the collections returned by all three Map's “collection view methods" are
fail-safe >
map.keySet().iterator(), map.values().iterator(), map.entrySet().iterator()
 ConcurrentHashMap

 ConcurrentSkipListMap

SUMMARY of fail-fast, fail-safe and java.util.ConcurrentModificationException in java >


What’s the main difference variables maintained when iteration is done on ArrayList and CopyOnWriteArrayList in java?
Iterator returned by ArrayList maintains variables called modCount (The number of times this list has been structurally
modified. Any changes to size of list are called structural modifications).
So, any structural modification made to ArrayList during iteration will throw ConcurrentModificationException in java
Iterator returned by CopyOnWriteArrayList maintains variables called snapshot ( it is copy of array (not the original
array)
So, any structural modification made to CopyOnWriteArrayList during iteration won’t throw any Exception.

Does finally block always execute? Will finally block execute when System.exit is called?
finally is not executed when System.exit is called, finally block is also not executed when JVM crashes because of some
java.util.Error.
try or try-catch block can be followed by finally block >
 try-finally block, or

try{
//Code to be enclosed in try-finally
block
}finally{
}

 try-catch-finally block.

try{
//Code to be enclosed in try-catch-finally block
}catch(Exception e){
}finally{
}

finally block can only exist if try or try-catch block is there, finally block can’t be used alone in java.
Using only finally block will cause compilation error
finally{
//only finally block will cause compilation error
}

Features of finally >


 finally block is always executed irrespective of exception is thrown or not.
 finally is keyword in java.
 finally block is optional in java, we may use it or not.

finally block is not executed in following scenarios >


 finally is not executed when System.exit is called.
 if in case JVM crashes because of some java.util.Error.

Programming time - we will create following programs to demonstrate finally block in java >

Program 1 to show finally block is executed when exception is not thrown.


package finally1;
public class ExceptionTest {
public static void main(String[] args) {

try{
int i=10/1;
}catch(ArithmeticException e){
System.out.println("ArithmeticException handled in catch block");
}
finally{
System.out.println("finally block executed");
}
System.out.println("code after try-catch-finally block");
}
}
/*OUTPUT
finally block executed
code after try-catch-finally block
*/

Program 2 to show finally block is executed when exception is thrown, in this case catch and finally both blocks are
executed.
package finally2;
public class ExceptionTest {
public static void main(String[] args) {
try{
int i=10/0; //will throw ArithmeticException
}catch(ArithmeticException e){
System.out.println("ArithmeticException handled in catch block");
}
finally{
System.out.println("finally block executed");
}
System.out.println("code after try-catch-finally block");
}
}
/*OUTPUT
ArithmeticException handled in catch block
finally block executed
code after try-catch-finally block
*/

Program 3 to show finally block is executed when exception is thrown and not handled properly, in this case catch blocks
does not executes, finally block executes alone.
package finally3;
public class ExceptionTest {
public static void main(String[] args) {
try{
int i=10/0; //will throw ArithmeticException
}catch(IndexOutOfBoundsException e){
System.out.println("IndexOutOfBoundsException handled in catch block");
}
finally{
System.out.println("finally block executed");
}
System.out.println("code after try-catch-finally block");
}
}
/*OUTPUT
finally block executed
Exception in thread "main" java.lang.ArithmeticException: / by zero
at finally3.ExceptionTest.main(ExceptionTest.java:7)
*/

It’s important to note in above program that finally block was executed but catch block didn’t because Exception wasn’t
handled properly in above program - program throwed ArithmeticException but we were handing
IndexOutOfBoundsException.
Also, sysout statement after try-catch-finally block wasn’t executed.

Program 4 to show finally is not executed when System.exit is called.

public class ExceptionTest {


public static void main(String[] args) {
try{
System.out.println("in try block");
System.exit(0);
}finally{
System.out.println("finally block executed");
}
}
}
/*OUTPUT
in try block
*/
In the above program, finally block is not executed when System.exit is called.

Bit more about System.exit(n) method >


 System.exit terminates JVM.
 Parameter
o Passing zero as parameter means normal termination &
o Passing non-zero as parameter means abnormal termination.
 System.exit(n) internally calls Runtime.getRuntime().exit(n)

Program 5 to show what will happen when catch and finally both return some value.
When catch and finally block both return value, method will ultimately return value returned by finally block
irrespective of value returned by catch block.

public class ExceptionTest {


public static void main(String[] args) {
System.out.println("method return -> "+m());
}

static String m(){


try{
int i=10/0; //will throw ArithmeticException
}catch(ArithmeticException e){
return "catch";
}finally{
return "finally";
}

}
}
/*OUTPUT
method return -> finally
*/
In above program, i=10/0 will throw ArithmeticException and enter catch block to return "catch", but ultimately control will
enter finally block to return "finally".
When try and finally block both return value, method will ultimately return value returned by finally block irrespective
of value returned by try block.
public class ExceptionTest {
public static void main(String[] args) {
System.out.println("method return -> "+m());
}

static String m(){


try{
int i=1;
return "try";
}finally{
return "finally";
}

}
}
/*OUTPUT
method return -> finally
*/
In above program, try block will "try", but ultimately control will enter finally block to return "finally".

Application of finally block in java programs >


 We may use finally block to execute code for database connection closing, because closing connection in try or
catch block may not be safe.
o Why closing connection in try block may not be safe?
o Because exception may be thrown in try block before reaching connection closing statement.
o Why closing connection in catch block may not be safe?
o Because inappropriate exception may be thrown in try block and we might not enter catch block to close
connection.

What are differences between checked and unchecked exceptions?


checked exceptions
checked exceptions are also known as compileTime exceptions.
Checked exceptions are those which need to be taken care at compile time.

Benefit of using compileTime Exception >


We cannot proceed until we fix compilation issues which are most likely to happen in program, this helps us in avoiding
runtime problems upto lot of extent.
Example- FileNotFoundException - Until we handle this exception, user will face compilation error, because at runtime
there is huge probability of file missing in the directory.

Which classes are which exception?


The class Exception and all its subclasses that are not also subclasses of RuntimeException are checked exceptions.

Exception propagation >


For propagating checked exceptions method must throw exception by using throws keyword.

unchecked exceptions
unchecked exceptions are also known as runtime exceptions.
Unchecked exceptions are those which need to be taken care at runtime.

Benefit of using RunTime Exception >


Whenever runtime exception occurs execution of program is interrupted, but by handling these kind of exception we avoid
such interruptions and end up giving some meaningful message to user.

Which classes are which exception?


The class RuntimeException and all its subclasses are unchecked exceptions.
Likewise,
The class Error and all its subclasses are unchecked exceptions.

Exception propagation >


unchecked exceptions are automatically propagated in java.

Differences between checked and unchecked exceptions >

Property checked exception unchecked exception

1 Also known as checked exceptions are also known as unchecked exceptions are also known as
compileTime exceptions. runtime exceptions.

2 Should be Checked exceptions are those which need to Unchecked exceptions are those which need to be
solved at be taken care at compile time. taken care at runtime.
compile or
runtime?

3 Benefit/ We cannot proceed until we fix compilation Whenever runtime exception occurs execution of
Advantage issues which are most likely to happen in program is interrupted, but by handling these
program, this helps us in avoiding runtime kind of exception we avoid such interruptions
problems upto lot of extent. and end up giving some meaningful message to
user.

4 Creating
custom/own
exception class UserException extends Exception { class UserException extends RuntimeException
UserException(String s) { {
super(s); UserException(String s) {
} super(s);
} }
}
By extending java.lang.Exception, we can
create checked exception. By extending java.lang.RuntimeException, we
can create unchecked exception.

5 Exception For propagating checked exceptions unchecked exceptions are automatically


propagation method must throw exception by using propagated in java.
throws keyword.

6 handling If superclass method throws/declare checked If superclass method throws/declare unchecked >
checked and exception >  overridden method of subclass can
unchecked  overridden method of subclass can declare/throw any unchecked /RuntimeException
exception while declare/throw narrower (subclass of) checked (superclass or subclass) (As shown in Program), or
exception (As shown in Program), or 
overriding overridden method of subclass cannot
superclass  overridden method of subclass cannot declare/throw any checked exception (As shown in
method declare/throw broader (superclass of) checked Program),
exception (As shown in Program), or
 overridden method of subclass can
declare/throw any unchecked
/RuntimeException (As shown in Program)

Which classes The class Exception and all its subclasses The class RuntimeException and all its
are which type that are not also subclasses of subclasses are unchecked exceptions.
of exception? RuntimeException are checked exceptions. Likewise,
either The class Error and all its subclasses are
checked or unchecked exceptions.
unchecked
exception?

7 Most frequently SQLException, NullPointerException,


faced IOException, ArithmeticException
exceptions ClassNotFoundException, ArrayIndexOutOfBoundsException.
FileNotFoundException

What are exception handling keywords in java?


5 keyword in java exception handling
o try - Any exception occurring in try block is catched by catch block.
o catch - catch block is always followed by try block.
o finally finally block can can only exist if try or try-catch block is there, finally block can’t be used alone
in java.

throw exception in java


 throw is a keyword in java.
 throw keyword allows us to throw checked or unchecked exception.
throw unchecked exception >
 We need not to handle unChecked exception either by catching it or throwing it.

We throw NullPointerException (unChecked exception) and didn’t handled it, no compilation error was thrown.

throw checked exception >


 We need to handle checked exception either by catching it, or
 throwing it by using throws keyword. (When thrown, exception must be handled in calling environment)
If checked Exception is not handled either by try-catch or throws, we will face compilation error.
Program 1- Handling Exception in try-catch block where it was thrown.

import java.io.FileNotFoundException;
public class ExceptionTest {
public static void main(String[] args) {
m();
System.out.println("after calling m()");
}
static void m(){
try {
throw new FileNotFoundException();
} catch (FileNotFoundException e) {
System.out.println("FileNotFoundException handled in try-catch block");
}
}
}
/*OUTPUT
FileNotFoundException handled in try-catch block
after calling m()

*/
We throwed FileNotFoundException (checked exception) by using throw keyword and handled it in try-catch block.

Program 2- Handling Exception by throwing it from m() method (using throws keyword) and handling it in try-catch block
from where call to method m() was made.
import java.io.FileNotFoundException;
public class ExceptionTest {
public static void main(String[] args) {
try {
m();
} catch (FileNotFoundException e) {
System.out.println("FileNotFoundException handled in try-catch block");
}
System.out.println("after calling m()");
}
static void m() throws FileNotFoundException{
throw new FileNotFoundException();
}
}
/*OUTPUT
FileNotFoundException handled in try-catch block
after calling m()
*/
method m() propagated exception to calling method (i.e. main method) using throws.

Program 3- Throwing Exception from m() method and then again throwing it from calling method [ i.e. main method]
Ultimately exception is not handled properly in this case, but this approach is used in many live projects (i.e. in web
applications).
package throwChecked_3_throw_throw;
import java.io.FileNotFoundException;
public class ExceptionTest {
public static void main(String[] args) throws FileNotFoundException {
m();
System.out.println("after calling m()");
}
static void m() throws FileNotFoundException{
throw new FileNotFoundException();
}
}
/*OUTPUT
Exception in thread "main" java.io.FileNotFoundException
at throwChecked_3_throw_throw.ExceptionTest.m(ExceptionTest.java:12)
at throwChecked_3_throw_throw.ExceptionTest.main(ExceptionTest.java:8)
*/
Please note that System.out.println("after calling m()") statement wasn't executed.

method m() propagated exception to calling method (i.e. main method) using throws, and main propagated exception to
JVM using throws.

throws exception in java


throws is written in method’s definition to indicate that method can throw exception.
throws unChecked exception >
 We need not to handle unChecked exception either by catching it or throwing it.

Above code throws NullPointerException (unChecked exception) and didn’t handled it from where method m() was called
and no compilation error was thrown.
throws Checked exception >
 We need to handle checked exception either by catching it or throwing it further, if not handled we will face
compilation error.

Program 1 - Handling Exception by throwing it from m() method (using throws keyword) and handling it in try-catch block
from where call to method m() was made.

import java.io.FileNotFoundException;
public class ExceptionTest {
public static void main(String[] args) {
try {
m();
} catch (FileNotFoundException e) {
System.out.println("FileNotFoundException handled in try-catch block");
}
System.out.println("after calling m()");
}
static void m() throws FileNotFoundException{

}
}
/*OUTPUT
after calling m()
*/
method m() propagated exception to calling method (i.e. main method) using throws.

Program 2 - Throwing Exception from m() method and then again throwing it from calling method [ i.e. main method]
Ultimately exception is not handled properly in this case, but this approach is used in many live projects (i.e. in web
applications).
import java.io.FileNotFoundException;
public class ExceptionTest {
public static void main(String[] args) throws FileNotFoundException {
m();
System.out.println("after calling m()");
}
static void m() throws FileNotFoundException{

}
}
/*OUTPUT
after calling m()

*/

method m() propagated exception to calling method (i.e. main method) using throws, and main propagated exception to
JVM using throws.

Differences between Exception and Error in java


In this post we will be discussing differences between java.lang.Exception and java.lang.Error
Differences between Exception and Error in java >

Property Exception Error

1 serious Exception does not indicate any Error indicates some serious problems that our
problem? serious problem. application should not try to catch.

2 divided into Exception are divided into checked Error are not divided further into such classifications.
checked and and unchecked exceptions.
unchecked

3 Which classes The class Exception and all its Error and its subclasses are regarded as unchecked
are which type subclasses that are not also exceptions
of exception? subclasses of RuntimeException are
either checked exceptions.
checked or
unchecked The class RuntimeException and all
exception? its subclasses are unchecked
exceptions.
Likewise,
The class Error and all its subclasses
are unchecked exceptions.

4 Most frequently checked exceptions> VirtualMachineError, IOError, AssertionError,


faced exception SQLException, ThreadDeath,
and errors IOException, OutOfMemoryError, StackOverflowError.
ClassNotFoundException
unchecked exceptions>
NullPointerException,
ArithmeticException,

5 Why to catch or Application must catch the Exception Application must not catch the Error because they does
not to catch? because they does not cause any major cause any major threat to application.
threat to application. Example >
Let’s say errors like OutOfMemoryError and
StackOverflowError occur and are caught then JVM
might not be able to free up memory for rest of
application to execute, so it will be better if application
don’t catch these errors and is allowed to terminate.

Differences between throw and throws in java


Differences between throw and throws in java >
throw throws

1 throw keyword is used to throw an exception explicitly. throws keyword is used to declare an
exception.

2 throw is used inside method. throws is used in method declaration.


Example > Example >
static void m(){ static void m() throws
throw new FileNotFoundException(); FileNotFoundException{
} }

3 throw is always followed by instanceof Exception class. throws is always followed by name of
Example > Exception class.
throw new FileNotFoundException() Example >
throws FileNotFoundException

4 throw can be used to throw only one exception at time. throws can be used to throw multiple
Example > exception at time.
throw new FileNotFoundException() Example >
throws FileNotFoundException,
NullPointerException
and many more...

5 throw cannot propagate exception to calling method. throws can propagate exception to calling
method.
Please see these programs to understand how
exception is propagated to calling method.
Program 1 - Handling Exception by throwing
it from m() method (using throws keyword)
and handling it in try-catch block from where
call to method m() was made.
Program 2 - Throwing Exception from m()
method and then again throwing it from calling
method [ i.e. main method]

Similarities between throw and throws in java >


Though there are not much similarities between two, but both are keywords in java.
Differences between Final, Finally and Finalize in java
Difference between Final, Finally and Finalize

final finally finalize


1 final can be applied to variable, method and class in java. finally is a finalize is a method.
block.

2 2.1) Final variable try or try- finalize method is called


final memberVariable catch block before garbage collection by
final local variable can be JVM,
final static variable followed by finalize method is called for
Final memberVariable of class must be initialized at time of finally block any clean up action that may
declaration, once initialized final memberVariable cannot be > be required before garbage
assigned a new value. try-finally collection.
Final variables are called constants in java. block, or
@Override
class FinalTest { try{ protected void finalize()
final int x=1; //Code to throws Throwable {
//memberVariable/instanceVariable be try {
} enclosed System.out.println("in
in try- finalize() method, "
If constructor is defined then final memberVariable can be finally +
initialized in constructor but once initialized cannot be assigned a block "doing cleanup
new value. }finally{ activity");
class FinalTest { }
final int x; } catch (Throwable
//memberVariable/instanceVariable throwable) {
try-catch- throw throwable;
FinalTest() { finally block.
x = 1; //final memberVariable can be }
initialized in constructor. try{ }
} //Code to
} be finalize() method is defined
enclosed in java.lang.Object
Final local variable can be left uninitialized at time of declaration in try-
and can be initialized later, but once initialized cannot be assigned a catch-
new value. finally
class FinalTest { block
void method(){ }catch(Exc
final int x; //uninitialized at time of eption e){
declaration }finally{
x=1; }
}
} finally block
can can only
exist if try or
Final static variable of class must be initialized at time of try-catch
declaration or can be initialized in static block, once initialized final block is there,
static variable cannot be assigned a new value. finally block
can’t be used
If static block is defined then final static variable can be initialized alone in java.
in static block, once initialized final static variable cannot be
assigned a new value.
finally block
class FinalTest { is not
final static int x; //static variable executed in
static{ //static block following
x=1; scenarios >
} finally is not
} executed
when
System.exit is
called.
2.2) Final method
if in case
Final method cannot be overridden, any attempt to do so will cause
JVM crashes
compilation error.
because of
some
java.util.Erro
r.
Runtime polymorphism is not applicable on final methods because
they cannot be inherited.

2.3) Final class


Final class cannot be extended, any attempt to do so will cause
compilation error.

3 - finally block We can force early garbage


can only exist collection in java by using
if try or try- following methods >
catch block is System.gc();
there, finally Runtime.getRuntime().gc()
block can’t be ;
used alone in System.runFinalization();
java. Runtime.getRuntime().run
Finalization();

4 - finally is If any uncaught exception is


always thrown inside finalize
executed method -
irrespective of exception is ignored,
exception thread is terminated and
thrown. object is discarded.
Note : Any exception
thrown by the finalize
method causes the
finalization of this object to
be halted, but is otherwise
ignored.

5 - Currently JVM does not guarantee


executing which daemon thread will
thread calls invoke the finalize method
finally for an object.
method.

6 final is a keyword in java. finally Is a finalize is not a keyword in


keyword in java.
java.

What is exception propagation in java?


Whenever methods are called stack is formed and an exception is first thrown from the top of the stack and if it is not caught,
it starts coming down the stack to previous methods until it is not caught.
If exception remains uncaught even after reaching bottom of the stack it is propagated to JVM and program is terminated.

Exception propagation in java - deep understanding of how checked and unchecked exceptions are propagated\

Exception Propagation >


Propagating unchecked exception (NullPointerException) >
unchecked exceptions are automatically propagated in java.

Now, i’ll be explaining you how unchecked exception was propagated.


Let’s see step by step what happened in above program >
 JVM called main method
 step 1 - main called method1()
 step 2 - method1 called method2()
 step 3 - method2 called method3()
 step 4 - method3 automatically propagated exception to method2() [because, unchecked exceptions are
propagated automatically]
 step 5 - method2 automatically propagated exception to method1() [because, unchecked exceptions are
propagated automatically]
 step 6 - method2 automatically propagated exception to main() [because, unchecked exceptions are propagated
automatically]
 main() automatically propagated exception to JVM [because, unchecked exceptions are propagated
automatically]

Let's see how stack of methods is formed >

In the above program, stack is formed and an exception is first thrown from the top of the stack [ method3() ] and it remains
uncaught there, and starts coming down the stack to previous methods to method2(), then to method1(), than to main() and
it remains uncaught throughout.
exception remains uncaught even after reaching bottom of the stack [ main() ] so it is propagated to JVM and ultimately
program is terminated by throwing exception [ as shown in output ].

Propagating checked exception (FileNotFoundException) using throws keyword >

For propagating checked exceptions method must throw exception by using throws keyword.
Now, i’ll be explaining you how checked exception was propagated.
Let’s see step by step what happened in above program >
 JVM called main method
 step 1 - main called method1()
 step 2 - method1 called method2()
 step 3 - method2 called method3()
 step 4 - method3 propagated exception to method2() using throws keyword.[because, checked exceptions are not
propagated automatically]
 step 5 - method2 propagated exception to method1() using throws keyword.[because, checked exceptions are not
propagated automatically]
 step 6 - method2 propagated exception to main() using throws keyword.[because, checked exceptions are not
propagated automatically]
 main() propagated exception to JVM using throws keyword.[because, checked exceptions are not propagated
automatically]

What is cloning in java?


Cloning is done for copying the object, cloning can be done using shallow or deep copy, we will discuss it later in post.

Few key points about clone method>


 1) Definition of clone method -

protected native Object clone() throws CloneNotSupportedException;


 Clone is a protected method - clone method can’t be called outside class without inheritance.

 Clone is native method, if not overridden its implementation is provided by JVM.

 It returns Object - Means explicitly cast is needed to convert it to original object.

 2) By default clone method do shallow copy.


 3) Class must implement marker interface java.lang.Cloneable. If class doesn’t implement Cloneable than calling

clone method on its object will throw CloneNotSupportedException.

 4) shallow copy- If we implement Cloneable interface, we must override clone method and call super.clone() from

it, invoking super.clone() will do shallow copy.

 5) Deep copy - We need to provide custom implementation of clone method for deep copying. When the copied

object contains some other object its references are copied recursively in deep copy.

8 important points about cloning in java>

 1) Definition of clone method -

protected native Object clone() throws CloneNotSupportedException;

 Clone method is present in java.lang.Object class.

 Clone is a protected method - clone method can’t be called outside class without inheritance.

 Clone is native method, if not overridden its implementation is provided by JVM.

 It returns Object - Means explicitly cast is needed to convert it to original object.

 Clone is not a keyword in java.

 2) By default clone method do shallow copy.

 3) Class must implement marker interface java.lang.Cloneable. If class doesn’t implement Cloneable than calling

clone method on its object will throw CloneNotSupportedException.

 4) shallow copy- If we implement Cloneable interface, we must override clone method and call super.clone() from

it, invoking super.clone() will do shallow copy.

 5) Deep copy - We need to provide custom implementation of clone method for deep copying. When the copied

object contains some other object its references are copied recursively in deep copy. When you implement deep copy be

careful as you might fall for cyclic dependencies

 6) Constructor of object is not called when clone method is called.

Shallow copy >

Let’s say we want to shallow copy emp object using clone method.
In shallow copy, different object is created after cloning (i.e. clonedEmp is created from emp) but member variables keep

on referring to same object (i.e. name and map).

Program for shallow copy>

import java.util.*;
public class CloneShallow implements Cloneable {
private String name;
private Map<Integer, Integer> map;
public CloneShallow(String name,Map<Integer,Integer> map){
this.name=name;
this.map=map;
}

/*
* override clone method for doing shallow copy.
*/
@Override
public Object clone() {
System.out.println("Doing shallow copy");
try {
return super.clone();
} catch (CloneNotSupportedException e) {
return null;
}
}
public static void main(String[] args) throws CloneNotSupportedException
{

Map<Integer,Integer> map=new HashMap<Integer,Integer>();


map.put(11, 11);
CloneShallow obj=new CloneShallow("ankit",map);
CloneShallow clonedObj=(CloneShallow)obj.clone();
System.out.println(obj==clonedObj); //false
System.out.println(obj.name==clonedObj.name); //true
System.out.println(obj.map==clonedObj.map); //true

}
}
/*OUTPUT
Doing shallow copy
false
true
true
*/

Deep copy >

Let’s say we want to deep copy emp object using clone method.
In deep copy, different object is created after cloning (i.e. clonedEmp is created from emp) , also member variables starts

referring to different objects (i.e. name and map).

Program for deep copy>

package clone;
import java.util.*;
public class CloneDeep implements Cloneable {
public CloneDeep(String name, Map<Integer,Integer> map){
this.name=name;
this.map=map;
}

private String name;


private Map<Integer,Integer> map;

/*
* override clone method for doing deep copy.
*/
@Override
public CloneDeep clone(){
System.out.println("Doing deep copy");
Map<Integer,Integer> map=new HashMap<Integer,Integer>();
Iterator<Integer> it=this.map.keySet().iterator();
while(it.hasNext()){
Integer key=it.next();
map.put(key,this.map.get(key) );
}

CloneDeep cloneDetailedDeep=new CloneDeep(new String(name),


map);

return cloneDetailedDeep;
}
public static void main(String[] args) throws CloneNotSupportedException {

Map<Integer,Integer> map=new HashMap<Integer,Integer>();


map.put(1, 11);

CloneDeep obj1=new CloneDeep("sam",map);

CloneDeep obj2=(CloneDeep)obj1.clone();

System.out.println(obj1==obj2); //false
System.out.println(obj1.name==obj2.name); //false
System.out.println(obj1.map==obj2.map); //false
}
}
/*OUTPUT
Doing deep copy
false
false
false
*/

package com.home.java;
import java.util.*;

public class DeepCopy


{
Integer id;
String name;
Double salary;
Map<Integer,Integer> map;
int val[];

public DeepCopy(Integer id, String name, Double salary, Map<Integer, Integer> map, int[] val) {
this.id = id;
this.name = name;
this.salary = salary;
this.map = map;
this.val = val;
}

//doing deep copy


protected DeepCopy clone() throws CloneNotSupportedException
{
//map cloning.......
Map<Integer,Integer> newMap=new HashMap<Integer,Integer>();
Set<Integer> keySet=map.keySet();
Iterator<Integer> keyIterator=keySet.iterator();
while(keyIterator.hasNext())
{
Integer key=keyIterator.next();
newMap.put(key,map.get(key));
}
//array cloning......

int newArr[]=new int[val.length];


for(int i=0;i<val.length;i++)
{
newArr[i]=val[i];
}

return new DeepCopy(new Integer(id),new String(name),new Double(salary),newMap,newArr);


}

@Override
public String toString() {
return "DeepCopy{" +
"id=" + id +
", name='" + name + '\'' +
", salary=" + salary +
", map=" + map +
", val=" + Arrays.toString(val) +
'}';
}
}

package com.home.java;

import java.util.HashMap;
import java.util.Map;

public class DeepMainApp


{
public static void main(String[] args) throws CloneNotSupportedException{
Map<Integer,Integer> map=new HashMap<Integer, Integer>();
map.put(1234,5678);
map.put(5678,989);
map.put(5556,7788);
map.put(1919,8871);
int arr[]={2,3,1,4,5};

DeepCopy dCopy=new DeepCopy(12345, "kaushal",7826284.111,map,arr);


System.out.println("Before copy=====");
System.out.println(dCopy);
System.out.println();
System.out.println("After copy=====");
DeepCopy copieObject=dCopy.clone();
System.out.println(copieObject);
System.out.println("check reference vriable. i.e both objects");
System.out.println("either refer a same varaibles or differet variables");
System.out.println(dCopy.id==copieObject.id);//refer same variables
System.out.println(dCopy.name==copieObject.name);//refer same variables
System.out.println(dCopy.salary==copieObject.salary);//refer same variables
System.out.println(dCopy.map==copieObject.map);//refer same variables
System.out.println(dCopy.val==copieObject.val);//refer diff variables
System.out.println(dCopy==copieObject); //two different objects
}
}

C:\Users\kaushal.kumar1\.jdks\corretto-11.0.8\bin\java.exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA


Community Edition 2020.2.2\lib\idea_rt.jar=54113:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2020.2.2\
bin" -Dfile.encoding=UTF-8 -classpath C:\kaushal\core-java\target\classes com.home.java.DeepMainApp
Before copy=====
DeepCopy{id=12345, name='kaushal', salary=7826284.111, map={1234=5678, 5556=7788, 5678=989, 1919=8871},
val=[2, 3, 1, 4, 5]}

After copy=====
DeepCopy{id=12345, name='kaushal', salary=7826284.111, map={1234=5678, 5556=7788, 5678=989, 1919=8871},
val=[2, 3, 1, 4, 5]}
check reference vriable. i.e both objects
either refer a same varaibles or differet variables
false
false
false
false
false
false

Process finished with exit code 0

5 Different techniques for deep copying>

Jackson JSON can also be used for serializing object to JSON and read it back.
Apache commons allows you to do deep cloning

Let's say emp is reference variable referring to object of Employee class.


Employee empClone = org.apache.commons.lang.SerializationUtils.clone(emp);

Dozer - Dozer for deep cloning.


Dozer is a Java Bean to Java Bean mapper that recursively copies data from one object to another, it is an open source
mapping framework that is robust, generic, flexible, reusable, and configurable.

Deep cloning using Serialization and deserialization - Simply serialize object by creating object of ObjectOutputStream
and then using its writeObject method. And then deserializing the object. (As done in above program)
Deep cloning using Reflection - (As done in above program)

Deep copy using Serialization and Deserialization >

Program for deep copy using Serialization and Deserialization >

Let’s say we want to deep copy emp object using serialization.


In serialization and deserialization process, different object is created after deserialization ( i.e. deSerializedEmp is created

from emp) , also member variables starts referring to different objects (i.e. name and map).

package clone;
class Employee implements Serializable {

private static final long serialVersionUID = 1L;


private String name;
private Map<Integer,Integer> map;

public Employee(String name,Map<Integer,Integer> map) {


this.name = name;
this.map=map;
}
@Override
public String toString() {
return "Employee [name=" + name + "]";
}
public String getName() {
return name;
}
public Map<Integer, Integer> getMap() {
return map;
}
}
/**
* Main class
*/
public class CloneUsingSerialization {
public static void main(String[] args) {
Map<Integer,Integer> map=new HashMap<Integer,Integer>();
map.put(1, 11);

Employee emp = new Employee("ankit",map);


try {
OutputStream fout = new FileOutputStream("ser.txt");
ObjectOutput oout = new ObjectOutputStream(fout);
System.out.println("Serialization process has started, "
+ "serializing employee object...");
oout.writeObject(emp);
fout.close();
oout.close();
System.out.println("employee Serialization completed.");

//DeSerialization process >

InputStream fin=new FileInputStream("ser.txt");


ObjectInput oin=new ObjectInputStream(fin);
System.out.println("\nDeSerialization process has started, " + "deSerializing employee object...");
Employee deSerializedEmp=(Employee)oin.readObject();
fin.close();
oin.close();
System.out.println("employee DeSerialization completed.");

System.out.println(emp==deSerializedEmp); //false
System.out.println(emp.getName()==deSerializedEmp.getName()); //false
System.out.println(emp.getMap()==deSerializedEmp.getMap()); //false

} catch (IOException | ClassNotFoundException e) {


e.printStackTrace();
}
}
}
/*OUTPUT
Serialization process has started, serializing employee objects...
Object Serialization completed.
DeSerialization process has started, displaying employee objects...
Object DeSerialization completed.
false
false
false
*/

Why we use serialVersionUID ?


The serialization at runtime associates with each serializable class a version number, called a serialVersionUID, which is used during
deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect
to serialization.

Why so we use SerialVersionUID : SerialVersionUID is used to ensure that during deserialization the same class (that was used during
serialize process) is loaded.
Example: Suppose a person who is in UK and another person who is in India, both are going to perform serialization and deserialization
respectively. In this case to authenticate that the receiver who is in India is the authenticated person, JVM creates an Unique ID which is
known as SerialVersionUID.
In most of the cases, serialization and deserialization both activities are done by a single person with the same system and same location.
But in serialization, sender and receiver are not the same person i.e. the persons may be different, machine or system may be different and
location must be different then SerialVersionUID comes in the picture. In serialization, both sender and receiver should have .class file at
the time of beginning only i.e. the person who is going to do serialization and the person who is ready for deserialization should contain
same .class file at the beginning time only.

Serialization : At the time of serialization, with every object sender side JVM will save a Unique Identifier. JVM is responsible to
generate that unique ID based on the corresponding .class file which is present in the sender system.
Deserialization: At the time of deserialization, receiver side JVM will compare the unique ID associated with the Object with local class
Unique ID i.e. JVM will also create a Unique ID based on the corresponding .class file which is present in the receiver system. If both
unique ID matched then only deserialization will be performed. Otherwise we will get Runtime Exception saying InvalidClassException.
This unique Identifier is nothing but SerialVersionUID.
Problem of depending on default SerialVersionUID generated by JVM :
 Both sender and receiver should use the same JVM with respect to platform and version also. Otherwise receiver unable to
deserialize because of different SerialVersionUID.
 Both sender and receiver should use same .class file version. After serialization if there is any change in .class file at receiver side
then receiver unable to deserialize.
 To generate SerialVersionUID internally JVM may use complex algorithm which may create performance problem.
We can solve the above problem by configuring our own SerialVersionUID. We can configure our own SerialVersionUID as follows:

private static final long SerialVersionUID=10l;


A class Geeks which contains two variable which are going to Serialize
filter_none
brightness_4

// Java program to illustrate


// implementation of User-defined
// SerialVersionUID
class Geeks {

// User-defined SerialVersionUID
private static final long SerialVersionUID = 10l;
int i = 10;
int j = 20;
}
Program of Sender side which is going to Serialize object:
filter_none
brightness_4
// Java program to illustrate
// implementation of User-defined
// SerialVersionUID
import java.io.*;
class Sender {
public static void main(String[] args)
{
Geeks g = new Geeks();
// Here xyz.ser is the file name where the object is
// going to serialize
FileOutputStream fos = new FileOutputStream("xyz.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(g);
}
}
Program of Receiver side which is going to deserialize
filter_none
brightness_4

// Java program to illustrate


// implementation of User-defined
// SerialVersionUID
import java.io.*;
class Receiver {
public static void main(String[] args)
{
// Here xyz.ser is the file name where the object is
// going to Deserialized
FileInputStream fis = new FileInputStream("xyz.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
Geeks g1 = (Geeks)ois.readObject();
System.out.println("Deserialized Object Value:" + g1.i + "..."+g1.j);
}
}
Output:
We can see the file which is xyz.txt where object is Serialize and also the output when we deserialize the Object:

Why Static method cannot be overridden in java>

It's one of the favourite question of interviewers. Intention is to test few basic core java concepts.
Static method cannot be overridden in java, any attempt to do this will not cause compilation error, but the results won’t
be same when we would have overridden non-static methods.
But why?
Overriding in Java means that the method would be called on the run time based on type of the object and not on the compile
time type of it .

But static methods are class methods access to them is always resolved during compile time only using the compile time type
information.

Accessing static method using object references is a bad practice (we must access static variable using Class Name) and just
an extra liberty given by the java designers.
EXAMPLE>
In below program access to SuperClass’s static method() is resolved during compile time only using the compile time type
information (i.e. by using SuperClass obj), means calling obj.method() is always going to invoke static method() of
SuperClass.
Assign any sub type object to reference of superclass [obj=new SubClass()] won’t have any impact on call to static method
at runtime.
Accessing static method using object references is bad practice (discussed above) and just an extra liberty given by the java
designers.

Program to static method cannot be overridden in java>


class SuperClass{
static void method(){
System.out.println("superClass method");
}
}
class SubClass extends SuperClass{
static void method(){
System.out.println("SubClass method");
}
}
public class StaticMethodTest {

public static void main(String[] args) {


SuperClass obj=new SubClass();
obj.method();
}

}
/*OUTPUT
superClass method
*/

If non-static methods would have been used in above program, output would have been
subClass method

Important points you must know about overriding static methods in java >

 Static method cannot be overridden, any attempt to do this will not cause compilation error. (Discussed above)
 Static method cannot be overridden with non-static method, any attempt to do this will cause compilation error.
 Non-static method cannot be overridden with static method, any attempt to do this will cause compilation error.

Is overriding of private method allows in java?

No, private methods are inherited in subclass and hence cannot be overridden.
Though subclass can have same name of private method in superclass.

class A {
private final void m(){
System.out.println(1);
}
}
class B extends A {
void m(){
System.out.println(2);
}
}

What is difference between Method overloading and Method overriding in java?

Method overloading and Method overriding forms base of core java. It’s very important to differentiate between two.
Both have been used intensively in java Api’s. This is one the most prominently asked important interview question in java.

Method overloading Method overriding


1 When a class have same method name Method overriding - Method of superclass is overridden in subclass to
with different argument, than it is provide more specific implementation.
called method overloading.

2 Method is overloaded by - keeping In Method overriding - Method of superclass is overridden in subclass


same name of method and only when overriding method of subclass in java -
changing number of arguments

Let’s compare with method overriding 1. Method name - Have same name as of superclass method,
in java.
2. Access modifier - Must not have more restrictive modifier.
Example - public method cannot be overridden by private method.
1. Method name - same
method name.

2. Access modifier - Does not


matter.

3. Return type - Java allow overriding by changing the return


type, but only Covariant return type are allowed in java.
4. Number of parameters in java - Have same number of
parameters in java.
5. Exception thrown -
3. Return type - Does not  Overriding method must not throw new or broader
matter. checked exception,
 though Overriding method may throw new
narrower(subclass) of checked exception or
 Overriding method can throw any runtime exception
in java.
4. Number of parameters in
java - Have different For more detail on this point please Read : Throw/declare checked and
number of parameters unchecked exception while overriding superclass method in java
5. Exception thrown - Does
not matter.

3 Method overloading is generally done Method overriding is always done in subClass in java.
in same class but can also be done in
SubClass (See Program 3)

4 Both Static and instance method can Only instance methods can be overridden in java.
be overloaded in java.
Static methods can’t be overridden in java. (Please refer this article for
detailed analysis and explanation with program)

5 Main method can also be overloaded Main method can’t be overridden in java, because main is static method
in java (In Program 4) and static methods can’t be overridden in java (as mentioned in above
point)

6 private methods can be overloaded private methods can’t be overridden in java, because private methods are
in java. not inherited in subClass in java.

7 final methods can be overloaded in final methods can’t be overridden in java, because final methods are not
java. inherited in subClass in java.

8 Call to overloaded method is bonded Call to overridden method is bonded at runtime in java.
at compile time in java.

9 Method overloading concept is also Method overriding concept is also known as runtime time polymorphism
known as compile time in java.
polymorphism in java.

Now we will learn differences between Method overloading and Method overriding in java with program and examples.

Example of method overloading in java -


/*
* Method to calculate sum of 2 arguments
*/
public void sum(int x, int y) {
System.out.println("sum of 2 arguments = "+ (x+y));
}
/*
* Method to calculate sum of 3 arguments
*/
public void sum(int x, int y, int z) {
System.out.println("sum of 3 arguments = "+ (x+y+z));
}
sum() method logically perform almost similar tasks and the only difference is in number of arguments. Method overloading enables
same method name sum() to be reused in program in java.

/*
* superclass - Animal
*/
class Animals {
void food() {
System.out.println("Animal may eat flesh, grass or ....");
}
}
/*
* subclass of Animal - Lion
*/
class Lion extends Animals {
@Override
void food() {
System.out.println("Lion eat - flesh");
}
}

Access modifier restrictions in decreasing order:

private
default
protected
public
i.e. private is more restricted then default and default is more restricted than protected and so on.

Example 1:
class A {
protected void method()
{
System.out.println("Hello");
}
}

public class B extends A {

// Compile Time Error


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

public static void main(String args[])


{
B b = new B();
b.method();
}
}
Output:
Compile Time Error
Note: In the above Example Superclass class A defined a method whose access modifier is protected. While doing method overriding in
SubClass Class B we didn’t define any access modifier so Default access modifier will be used. By the rule, Default is more restricted then
Protected so this program will give compile time error. Instead of default, we could’ve used public which is less restricted then protected.

Example 2:

filter_none
edit
play_arrow

brightness_4
class A {
protected void method()
{
System.out.println("Hello");
}
}

public class B extends A {


public void method()
{
System.out.println("Hello");
}

public static void main(String args[])


{
B b = new B();
b.method();
}
}
Output:
Hello
Note: In the above Example Superclass class A defined a method whose access modifier is protected. While doing method overriding in
SubClass Class B we define access modifier as Public. Because Public access modifier is less restricted than Protected hence this program
compiles successfully.

What is difference between equals method and == operator in java? And what will be output of following code
snippets?
Code snippet 1 >
String s1 = new String("abc");
String s2 = new String("abc");

System.out.println(s1.equals(s2));

Code snippet 2 >


StringBuffer sb1 = new
StringBuffer("abc");
StringBuffer sb2 = new
StringBuffer("abc");

System.out.println(sb1.equals(sb2));

equals method
By default equals method checks for referential equality (Class may override the method and provide different functionality)
By default if x == y returns true then equals method also returns true.
Example -
>StringBuffer class doesn’t overrides equals method of Object class. The result is true if both references are referring to same
StringBuffer object.
>String class overrides equals method of Object class and compares one string object to the other string object. The result is true if
characters in both String object appears in same order.

Output of Code snippet 1 > true


Output of Code snippet 2 > false

== operator
The == operator checks for referential equality of object, it checks whether two references are referring to same object or
not.

Let’s test == operator with String Object >


String s1 = new String("abc");
String s2 = new String("abc");

System.out.println(s1==s2); //false

Why s1==s2 returns false?


String s1 = new String("abc");
string is created using new operator, which will force new string to be created in heap (not in string pool).

String s2 = new String("abc");


string is created using new operator, which will force new string to be created in heap (not in string pool)
Hence, s1 and s2 will be the two reference variables referring to different String objects.

Let’s test == operator with String Object (when two references are referring to same object) >
String s3 = "abc";
String s4 = "abc";
System.out.println(s3==s4);
//true

Why s3==s4 returns true?


String s3 = "abc";
No string with “abc” is there in pool, so JVM will create string in string pool and s3 will be a reference variable which will refer to it.

String s4 = "abc";
string with “abc” is there in pool, so s4 will be a reference variable which will refer to “abc” in string pool
Hence, s3 and s4 will be the two reference variables referring to same String object.

equals method
The equals method is defined in java.lang.Object class
By default equals method checks for referential equality (Class may override the method and provide different functionality)
By default if x == y returns true then equals method also returns true.

Let’s test equals method with String Object.


String class overrides equals method of Object class and compares one string object to the other string object. The result is true if
characters in both String object appears in same order.
String s1 = new String("abc");
String s2 = new String("abc");

System.out.println(s1.equals(s2));
//true

Why s1.equals(s2) returns true?


Because characters in both String object appears in same order.

Let’s test == operator and equals method with StringBuffer Object >

Let’s test == operator with StringBuffer Object >


StringBuffer sb1 = new
StringBuffer("abc");
StringBuffer sb2 = new
StringBuffer("abc");

System.out.println(sb1==sb2); //false

Why sb1==sb2 returns false?


StringBuffer sb1 = new StringBuffer("abc");
stringBuffer is created using new operator, which will create new StringBuffer object in heap.

StringBuffer sb2 = new StringBuffer("abc");


stringBuffer is created using new operator, which will create new StringBuffer object in heap.

Hence, sb1 and sb2 will be the two reference variables referring to different stringBuffer objects.

Let’s test equals method with StringBuffer Object.


The equals method is defined in java.lang.Object class.
By default equals method checks for referential equality (Class may override the method and provide different functionality).

StringBuffer class doesn’t overrides equals method of Object class. The result is true if both references are referring to same
StringBuffer object.
StringBuffer sb1 = new
StringBuffer("abc");
StringBuffer sb2 = new
StringBuffer("abc");

System.out.println(sb1.equals(sb2)); //false

Why sb1.equals(sb2) returns false?


StringBuffer class doesn’t overrides equals method of Object class and the result is false because both references are referring to
different StringBuffer object.

Additionally, you may enjoy few more experiments using == operator and equals method on String, here i have done few >
String s1 = "abc";
String s2 = "a" + "bc";
System.out.println(s1 == s2); // true
System.out.println(s1.equals(s2)); // true

String s3 = new String("abc");


String s4 = new String("a") + new String("bc");
System.out.println(s3 == s4); // false
System.out.println(s3.equals(s4)); // true

String x1 = "abc";
String x2 = new String(new char[] { 'a', 'b', 'c' });
System.out.println(x1 == x2); // false
System.out.println(x1.equals(x2)); // true
It’s important to know String are immutable - means any modification made to Sting objects produces new String Object.

Integer >
compare new Integer with new Integer using == operator for comparison >
public class Autoboxing{
public static void main(String[] args) {
Integer i1 = new Integer(3);
Integer i2 = new Integer(3);
System.out.println(i1 == i2);
//false
}
}
/*output
false
*/
Whenever new operator is used new objects are formed.
As we know, the == operator checks for referential equality of object, it checks whether two references are referring to same object or not,
i1 == i2 will always return false.
We must prefer to use equals method for comparing Integer objects i1 and i2 (because Integer class overrides equals method and checks for
value rather than referential equality) i1.equals(i2) will return true.
public class Autoboxing_EqualsMethod{
public static void main(String[] args) {
Integer i1 = new Integer(3);
Integer i2 = new Integer(3);
System.out.println(i1.equals(i2)); // true
}
}
/*output
true
*/

Tricky part comes when we compare Integer formed without using new operator >
compare Integer with Integer (where both Integers are formed without using new operator) using == operator for comparison >
public class Autoboxing{
public static void main(String[] args) {
Integer i1 = 3; //caches Integer object
Integer i2 = 3; //returns cached Integer
object
System.out.println(i1 == i2); //true
}
}
/*output
true
*/

Java caching >

A cache is an area of local memory that holds a copy of frequently accessed data that is otherwise expensive to get or compute.

What is constructor chaining in java?


whenever the object of class is created, implicitly default no-arg constructor of class and its super class constructor is called.

But how constructor of superclass is called?

A. Implicitly first statement of constructor is super(), [that means by default first statement of constructor super() is called, super() calls
implicit/explicit no-arg constructor of superclass].

Let’s we have superclass and subclass like this -


class SuperClass{
}
class SubClass extends SuperClass{
}

compiler will add default implicit no-arg constructor -


class SuperClass{
SuperClass(){ //no-arg constructor
super();
}
}
class SubClass extends SuperClass{
SubClass(){
super();
}
}

How many primitive data types are provided by java ?


Java provides 8 primitive data types

byte
short

char

int

long

float

boolean

Explain Implicit casting/promotion of primitive Data type in java?

Diagram of Implicit casting/promotion of primitive Data type in java >

boolean cannot be casted implicitly or explicitly to any other datatype.

What is Thread in java?

 Threads consumes CPU in best possible manner, hence enables multi processing. Multi threading reduces idle time of CPU
which improves performance of application.
 Thread are light weight process.
 A thread class belongs to java.lang package.
 We can create multiple threads in java, even if we don’t create any Thread, one Thread at least do exist i.e. main thread.
 Multiple threads run parallely in java.
 Threads have their own stack.
 Advantage of Thread : Suppose one thread needs 10 minutes to get certain task, 10 threads used at a time could complete that
task in 1 minute, because threads can run parallely.

How to implement Threads in java?

This is very basic threading question. Threads can be created in two ways i.e. by implementing java.lang.Runnable interface or extending
java.lang.Thread class and then extending run method.

1. Thread creation by implementing java.lang.Runnable interface. We will create object of class which implements Runnable interface :

MyRunnable runnable=new
MyRunnable();
Thread thread=new Thread(runnable);

2. And then create Thread object by calling constructor and passing reference of Runnable interface i.e. runnable object :

Thread thread=new
Thread(runnable);

We should implement Runnable interface or extend Thread class. What are differences between implementing Runnable and
extending Thread?
Well the answer is you must extend Thread only when you are looking to modify run() and other methods as well. If you are simply
looking to modify only the run() method implementing Runnable is the best option (Runnable interface has only one abstract method
i.e. run() ).

1. Multiple inheritance in not allowed in java : When we implement Runnable interface we can extend another class as well, but if we
extend Thread class we cannot extend any other class because java does not allow multiple inheritance. So, same work is done by
implementing Runnable and extending Thread but in case of implementing Runnable we are still left with option of extending some other
class. So, it’s better to implement Runnable.

2. Thread safety : When we implement Runnable interface, same object is shared amongst multiple threads, but when we extend Thread
class each and every thread gets associated with new object.

3. Inheritance (Implementing Runnable is lightweight operation) : When we extend Thread unnecessary all Thread class features are
inherited, but when we implement Runnable interface no extra feature are inherited, as Runnable only consists only of one abstract
method i.e. run() method. So, implementing Runnable is lightweight operation.

4. Coding to interface : Even java recommends coding to interface. So, we must implement Runnable rather than extending thread. Also,
Thread class implements Runnable interface.
5. Don’t extend unless you wanna modify fundamental behaviour of class, Runnable interface has only one abstract method i.e.
run() : We must extend Thread only when you are looking to modify run() and other methods as well. If you are simply looking to
modify only the run() method implementing Runnable is the best option (Runnable interface has only one abstract method i.e. run() ).
We must not extend Thread class unless we're looking to modify fundamental behaviour of Thread class.

6. Flexibility in code when we implement Runnable : When we extend Thread first a fall all thread features are inherited and our class
becomes direct subclass of Thread , so whatever action we are doing is in Thread class. But, when we implement Runnable we create a
new thread and pass runnable object as parameter, we could pass runnable object to executorService & much more. So, we have
more options when we implement Runnable and our code becomes more flexible.

7. ExecutorService : If we implement Runnable, we can start multiple thread created on runnable object with ExecutorService
(because we can start Runnable object with new threads), but not in the case when we extend Thread (because thread can be started only
once).

How can you ensure all threads that started from main must end in order in which they started and also main should
end in last? (Important)
Join() method - ensure all threads that started from main must end in order in which they started and also main
should end in last. Types of join() method in java

Interviewers tend to know interviewees knowledge about Thread methods. So this is time to prove your point by
answering correctly. We can use join() method to ensure all threads that started from main must end in order in which they started and
also main should end in last. In other words waits for this thread to die.
Calling join() method internally calls join(0);

10 salient features of join() method >

 Definition : join() We can use join() method to ensure all threads that started from main must end in order in which they started
and also main should end in last. In other words waits for thread to die on which thread has been called.

 Exception : join() method throws InterruptedException, in our case we have thrown exception.

 instance method : join() is a instance method, hence we need to have thread instance for calling this method.

 Thread state : when join() method is called on thread it goes from running to waiting state. And wait for thread to die.

 Not a native method : implementation of join() method is provided in java.lang.Thread class.


Let’s see definition of join() method as given in java.lang.Thread -
public final void join() throws InterruptedException;

 synchronized block : thread need not to acquire object lock before calling join() method i.e. join() method can be called from
outside synchronized block.

 Waiting time : join() method have got few options.


1. join() : Waits for this thread to die.

public final void join() throws


InterruptedException;
This method internally calls join(0). And timeout of 0 means to wait forever;
2. join(long millis) - Waits at most millis milliseconds for this thread to die. A timeout of 0 means to wait forever.

public static native void sleep(long millis) throws


InterruptedException;

3. join(long millis, int nanos) - Waits at most millis milliseconds plus nanos nanoseconds for this thread to die.

public static native void sleep(long millis,int nanos) throws


InterruptedException;

 Belongs to which class : join() method belongs to java.lang.Thread class.

To achieve we are going to create 2 threads on Runnable Object, create for loop in run() method and start both threads. After starting each
Thread call join() method on them to ensure they end in order in which they has started.

Full Program to show usage of join() method>


class MyRunnable implements Runnable{
public void run(){
System.out.println("in run() method");
for(int i=0;i<5;i++){

System.out.println("i="+i+" ,ThreadName="+Thread.currentThread().getName());
}
}
}
public class MyClass {
public static void main(String...args) throws InterruptedException{
System.out.println("In main() method");
MyRunnable runnable=new MyRunnable();
Thread thread1=new Thread(runnable);
Thread thread2=new Thread(runnable);

thread1.start();
thread1.join();

thread2.start();
thread2.join();

System.out.println("end main() method");


}
}
/*OUTPUT
In main() method
in run() method
i=0 ,ThreadName=Thread-0
i=1 ,ThreadName=Thread-0
i=2 ,ThreadName=Thread-0
i=3 ,ThreadName=Thread-0
i=4 ,ThreadName=Thread-0
in run() method
i=0 ,ThreadName=Thread-1
i=1 ,ThreadName=Thread-1
i=2 ,ThreadName=Thread-1
i=3 ,ThreadName=Thread-1
i=4 ,ThreadName=Thread-1
end main() method
*/
If we note output, all threads ended in order in which they were called and main thread has ended last.

First, main thread was called, it started Thread1 and then we called join() method on Thread1, once Thread1 ended main thread started
Thread2 and we called join() method on Thread2, once Thread2 ended main thread also ended.
In short - calling thread1.join() made main thread to wait until Thread-1 dies.

Let’s discuss waiting time in detail : join() method have got few options.
4. join() : Waits for this thread to die.

public final void join() throws


InterruptedException;
This method internally calls join(0). And timeout of 0 means to wait forever;

5. join(long millis) - Waits at most millis milliseconds for this thread to die. A timeout of 0 means to wait forever.

public static native void join(long millis) throws


InterruptedException;

6. join(long millis, int nanos) - Waits at most millis milliseconds plus nanos nanoseconds for this thread to die.

public static native void join(long millis,int nanos) throws


InterruptedException;

Let’s create a program to use join(long millis) >

First, join(1000) will be called on Thread-1, but once 1000 millisec are up, main thread can resume and start thread2 (main thread
won’t wait for Thread-1 to die).
class MyRunnable implements Runnable{
public void run(){
System.out.println("in run() method");
for(int i=0;i<5;i++){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("i="+i+" ,ThreadName="+Thread.currentThread().getName());
}
}
}
public class MyClass {
public static void main(String...args) throws InterruptedException{
System.out.println("In main() method");
MyRunnable runnable=new MyRunnable();
Thread thread1=new Thread(runnable);
Thread thread2=new Thread(runnable);
thread1.start();
thread1.join(1000); //once 1000 millisec are up, main thread can resume and start
thread2.
thread2.start();
thread2.join();
System.out.println("end main() method");
}
}
/*OUTPUT
In main() method
in run() method
i=0 ,ThreadName=Thread-0
i=1 ,ThreadName=Thread-0
in run() method
i=2 ,ThreadName=Thread-0
i=0 ,ThreadName=Thread-1
i=1 ,ThreadName=Thread-1
i=3 ,ThreadName=Thread-0
i=2 ,ThreadName=Thread-1
i=4 ,ThreadName=Thread-0
i=3 ,ThreadName=Thread-1
i=4 ,ThreadName=Thread-1
end main() method
*/

What is difference between starting thread with run() and start() method? (Important)

This is quite interesting question, it might confuse you a bit and at time may make you think is there really any difference between starting
thread with run() and start() method.
When you call start() method, main thread internally calls run() method to start newly created thread. So run() method is ultimately
called by newly created thread.
When you call run() method main thread rather than starting run() method with newly thread it start run() method by itself.
Let’s use start() method to start a thread>
class MyRunnable implements Runnable{
public void run(){ //overrides Runnable's run() method
System.out.println("in run() method");
System.out.println("currentThreadName= "+
Thread.currentThread().getName());
}
}
public class MyClass {
public static void main(String args[]){
System.out.println("currentThreadName= "+
Thread.currentThread().getName());
MyRunnable runnable=new MyRunnable();
Thread thread=new Thread(runnable);
thread.start();
}
}
/*OUTPUT
currentThreadName= main
in run() method
currentThreadName= Thread-0
*/
If we note output, when we called start() from main thread, run() method was called by new Thread (i.e. Thread-0).

Let’s use run() method to start a thread>

class MyRunnable implements Runnable{


public void run(){ //overrides Runnable's run() method
System.out.println("in run() method");
System.out.println("currentThreadName= "+
Thread.currentThread().getName());
}
}
public class MyClass {
public static void main(String args[]){
System.out.println("currentThreadName= "+
Thread.currentThread().getName());
MyRunnable runnable=new MyRunnable();
Thread thread=new Thread(runnable);
thread.run();
}
}
/*OUTPUT
currentThreadName= main
in run() method
currentThreadName= main
*/
If we note output, when we called run() from main thread, run() method was called by main Thread, not by newly created thread (i.e.
Thread-0).

Differences between synchronized and volatile keyword in Java? (Important)


Its very important question from interview perspective.

1. Volatile can be used as a keyword against the variable, we cannot use volatile against method declaration.
volatile void method1(){} //it’s illegal, compilation error.
volatile int i; //legal

While synchronization can be used in method declaration or we can create synchronization blocks. Variables cannot be
synchronized.
Synchronized method:
synchronized void method2(){} //legal

Synchronized block:
void method2(){
synchronized (this) {
//code inside synchronized block.
}
}

Synchronized variable (illegal):


synchronized int i; //it’s illegal, compilation error.

2. Volatile does not acquire any lock on variable or object, but Synchronization acquires lock on method or block in which it is
used.

3. Volatile variables are not cached, but variables used inside synchronized method or block are cached.
4. When volatile is used will never create deadlock in program, as volatile never obtains any kind of lock . But in case if
synchronization is not done properly, we might end up creating dead lock in program.

5. Synchronization may cost us performance issues, as one thread might be waiting for another thread to release lock on object. But
volatile is never expensive in terms of performance.
6. A compile-time error will occur if a final variable is declared volatile.

volatile final int x = 0; //The field x can be either final or volatile, not
both.
7. Performance issue - As volatile keyword is not cached in CPU, it is always read from main memory, so in terms of performance
it’s always expensive to use volatile keyword.
package com.home.java.demo.thread;

public class VolatileObject


{
private int counter=0;
private volatile int vcounter=0;

public int getCounter() {


return counter;
}

public int getVcounter() {


return vcounter;
}

public void increaseCounter()


{
counter++;
}
public void increaseVCounter()
{
vcounter++;
}
@Override
public String toString() {
return "VolatileObject{" +
"counter=" + counter +
", vcounter=" + vcounter +
'}';
}
}

package com.home.java.demo.thread;

public class VolatileThread implements Runnable


{
VolatileObject volatileObject;

public VolatileThread(VolatileObject volatileObject) {


this.volatileObject = volatileObject;
}

@Override
public void run()
{
// System.out.println(Thread.currentThread().getName()+" old NV: "+volatileObject.getCounter());
// volatileObject.increaseCounter();
// System.out.println(Thread.currentThread().getName()+" New NV: "+volatileObject.getCounter());
System.out.println(Thread.currentThread().getName()+" old V: "+volatileObject.getVcounter());
volatileObject.increaseVCounter();;
System.out.println(Thread.currentThread().getName()+" New V: "+volatileObject.getVcounter());
}
}

package com.home.java.demo.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class VolatileTest


{
public static void main(String[] args) throws InterruptedException{

VolatileObject volatileObject=new VolatileObject();


VolatileThread volatileThread=new VolatileThread(volatileObject);
Thread t1=new Thread(volatileThread);
Thread t2=new Thread(volatileThread);
Thread t3=new Thread(volatileThread);
t1.start();
t2.start();
t3.start();

}
}

C:\Users\kaushal.kumar1\.jdks\corretto-11.0.8\bin\java.exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition


2020.2.2\lib\idea_rt.jar=57131:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2020.2.2\bin" -Dfile.encoding=UTF-8 -
classpath C:\kaushal\core-java\target\classes com.home.java.demo.thread.VolatileTest
Thread-0 old V: 0
Thread-1 old V: 1
Thread-0 New V: 1
Thread-1 New V: 2
Thread-2 old V: 2
Thread-2 New V: 3

Process finished with exit code 0

Full program to show that how synchronization block can cost us performance,
we will create two threads on same object, then start both threads, either of the thread will acquire object lock and
other thread will wait to acquire lock until lock is released by thread which acquired it>
public class MyClass implements Runnable{

@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" is waiting for lock");
synchronized (this) {
try {
System.out.println(Thread.currentThread().getName()+" has acquired lock");
Thread.sleep(2000); //sleep for 2 seconds
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" has ended");
}

public static void main(String[] args) {


MyClass obj=new MyClass();
Thread thread1=new Thread(obj,"Thread-1");
Thread thread2=new Thread(obj,"Thread-2");
thread1.start();
thread2.start();
}
}
/*OUTPUT
Thread-1 is waiting for lock
Thread-2 is waiting for lock
Thread-1 has acquired lock
Thread-1 has ended
Thread-2 has acquired lock
Thread-2 has ended
*/

What happened in above program ?


Thread1 acquired object lock by entering in synchronized block & Thread2 was waiting for Thread1 to release lock and
enter in synchronization block, it costed us performance.

Here i have shown example code that how synchronized block can cost us performance, likewise you may call any
synchronized method from run() method, to see how synchronized method can cost us performance.

synchronization blocks and methods in java - Acquiring object lock - multiple threads may exist on same object but
only one thread of that object can enter synchronized block/method at a time.

In later posts we will learn how to acquire lock on class’s class object. Now, we will learn how to acquire object’s lock. It’s
very important to understand difference between object lock and class lock as well.

Thread can acquire object lock by-


1. Entering synchronized block or
2. by entering synchronized methods.

wait(), notify() and notifyAll() methods are always called from Synchronized block or synchronized methods only and
as soon as thread enters synchronized block it acquires object lock (by holding object monitor).

1) First let’s acquire object lock by entering synchronized block.

Let’s say there is one class MyClass and we have created it’s object and reference to that object is myClass. Now we can
create synchronization block, and parameter passed with synchronization tells which object has to be synchronized. In below
code, we have synchronized object reference by myClass.
MyClass myClass=new Myclass();
synchronized (myClass) {
//thread has acquired object lock on object referenced by myClass ( by acquiring myClass’s monitor.)
}

As soon thread entered Synchronization block, thread acquired object lock on object referenced by myClass (by acquiring
object’s monitor.)
Thread will leave lock when it exits synchronized block.

It’s important to know that multiple threads may exist on same object but only one thread of that object can enter
synchronized method at a time. Threads on different object can enter same method at same time.

Now, let’s create a program >


class MyRunnable implements Runnable {

public void run() {

synchronized (this) {
for(int i=0;i<5;i++){
System.out.println(i+" "+Thread.currentThread().getName()+" is executing");
try {
Thread.sleep(500);
} catch (InterruptedException e) {e.printStackTrace(); }
}

}
}
}
public class MyClass {
public static void main(String args[]) throws Exception {
MyRunnable obj = new MyRunnable();
Thread t1 = new Thread(obj,"Thread-1"); //Thread-1 on obj.
Thread t2 = new Thread(obj,"Thread-2"); //Thread-2 on obj.
t1.start();
t2.start();
}
}
/*OUTPUT
0 Thread-1 is executing
1 Thread-1 is executing
2 Thread-1 is executing
3 Thread-1 is executing
4 Thread-1 is executing
0 Thread-2 is executing
1 Thread-2 is executing
2 Thread-2 is executing
3 Thread-2 is executing
4 Thread-2 is executing
*/
If we note output, Thread-1 entered synchronization block and acquired obj’s lock meanwhile Thread-2 kept on waiting for
obj’s lock. And once Thread-1 completed Thread-2 acquired obj’s lock and started executing.

2) Now let’s acquire object lock by entering synchronized method.

Example- Let’s say there is one class MyClass and we have created it’s object and reference to that object is myClass. Than
we started thread and from run method we called synchronized void method1().

public synchronized void method1() {


//thread has acquired object lock on object referenced by myClass ( by acquiring myClass’s monitor.)
}

As soon as thread entered Synchronization method, thread acquired object lock on object referenced by myClass (by
acquiring object’s monitor.)
Thread will leave lock when it exits synchronized method.

It’s important to know that multiple threads may exist on same object but only one thread of that object can enter
synchronized method at a time. Threads on different object can enter same method at same time.

Now, let’s create a program >


class MyRunnable implements Runnable {

public void run() {


method1();

public synchronized void method1(){


for(int i=0;i<5;i++){
System.out.println(i+" "+Thread.currentThread().getName()+" is executing");
try {
Thread.sleep(500);
} catch (InterruptedException e) {e.printStackTrace(); }
}
}
}
public class MyClass {
public static void main(String args[]) throws Exception {
MyRunnable obj = new MyRunnable();
Thread t1 = new Thread(obj,"Thread-1"); //Thread-1 on obj.
Thread t2 = new Thread(obj,"Thread-2"); //Thread-2 on obj.
t1.start();
t2.start();
}
}
/*OUTPUT
0 Thread-1 is executing
1 Thread-1 is executing
2 Thread-1 is executing
3 Thread-1 is executing
4 Thread-1 is executing
0 Thread-2 is executing
1 Thread-2 is executing
2 Thread-2 is executing
3 Thread-2 is executing
4 Thread-2 is executing
*/
If we note output, Thread-1 entered synchronized method and acquired obj’s lock meanwhile Thread-2 kept on waiting for
obj’s lock. And once Thread-1 completed Thread-2 acquired obj’s lock and started executing.
But, it may also happen that Thread-2 might enter synchronized block first and in that case output will be -

/*OUTPUT
0 Thread-2 is executing
1 Thread-2 is executing
2 Thread-2 is executing
3 Thread-2 is executing
4 Thread-2 is executing
0 Thread-1 is executing
1 Thread-1 is executing
2 Thread-1 is executing
3 Thread-1 is executing
4 Thread-1 is executing
*/
If we note output, Thread-2 entered synchronized method and acquired obj’s lock meanwhile Thread-1 kept on waiting for
obj’s lock. And once Thread-2 completed Thread-1 acquired obj’s lock and started executing.

Can you again start Thread?


No, we cannot start Thread again, doing so will throw runtimeException java.lang.IllegalThreadStateException. The reason
is once run() method is executed by Thread, it goes into dead state.

Program to show that IllegalThreadStateException is thrown when we try to start thread again>
public class MyClass implements Runnable{

@Override
public void run() {
System.out.println("in run() method, method completed.");
}

public static void main(String[] args) {


MyClass obj=new MyClass();
Thread thread1=new Thread(obj,"Thread-1");
thread1.start();
thread1.start(); //will throw java.lang.IllegalThreadStateException at runtime
}
}
/*OUTPUT
in run() method, method completed.
Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.Thread.start(Unknown Source)
*/

What is race condition in multithreading and how can we solve it? (Important)
This is very important question, this forms the core of multi threading, you should be able to explain about race condition in
detail. When more than one thread try to access same resource without synchronization causes race condition.
So we can solve race condition by using either synchronized block or synchronized method. When no two threads can
access same resource at a time phenomenon is also called as mutual exclusion.

Race condition in multithreading and it's solution in java

synchronized block / synchronized method


This is very important question, this forms the core of multi threading, you should be able to explain this question in detail.
When more than one thread try to access same resource without synchronization causes race condition.
So we can solve race condition by using either synchronized block or synchronized method. When no two threads can
access same resource at a time phenomenon is also called as mutual exclusion.

Example (Train ticket booking)-


Let's say there is only 1 ticket available in train, and two passengers are trying to book that ticket at same time without
synchronization.
It might happen that both might end up booking up ticket, though only ticket was available, which is of course going to
create problem.
But if synchronization was there only of them would have been able to book ticket.

Program to show that without synchronization problems will happen when 2 passengers try to book train ticket, dat too
when only 1 ticket was available >
class TicketBooking implements Runnable{
int ticketsAvailable=1;

public void run(){

System.out.println("Waiting to book ticket for : "+Thread.currentThread().getName());


if(ticketsAvailable>0){
System.out.println("Booking ticket for : "+Thread.currentThread().getName());

//Let's say system takes some time in booking ticket (here we have taken 1 second time)
try{
Thread.sleep(1000);
}catch(Exception e){}

ticketsAvailable--;
System.out.println("Ticket BOOKED for : "+ Thread.currentThread().getName());
System.out.println("currently ticketsAvailable = "+ticketsAvailable);
}
else{
System.out.println("Ticket NOT BOOKED for : "+ Thread.currentThread().getName());
}

}
public class MyClass {
public static void main(String args[])
{
TicketBooking obj=new TicketBooking();

Thread thread1=new Thread(obj,"Passenger1 Thread");


Thread thread2=new Thread(obj,"Passenger2 Thread");

thread1.start();
thread2.start();

}
}
/*OUTPUT
Waiting to book ticket for : Passenger1 Thread
Waiting to book ticket for : Passenger2 Thread
Booking ticket for : Passenger1 Thread
Booking ticket for : Passenger2 Thread
Ticket BOOKED for : Passenger1 Thread
currently ticketsAvailable = 0
Ticket BOOKED for : Passenger2 Thread
currently ticketsAvailable = -1
*/
If we note the above program,
first Passenger1 Thread and Passenger2 Thread waited to book tickets.
Than, both threads tried to check the available ticket count and it was 1.
Both threads were able to book ticket.
And ultimately available ticket was reduced to -1, which is practically impossible, tickets count can never dip below 0.
RACE CONDITION PROBLEM : 1 ticket was booked by 2 passengers.

Now, let’s try to solve the problem by using synchronized block.

Program to show that with synchronization no problems will happen when 2 passengers try to book train ticket, dat too
when only 1 ticket was available>
class TicketBooking implements Runnable{
int ticketsAvailable=1;

public void run(){

System.out.println("Waiting to book ticket for : "+Thread.currentThread().getName());


synchronized (this) {
if(ticketsAvailable>0){
System.out.println("Booking ticket for : "+Thread.currentThread().getName());

//Let's say system takes some time in booking ticket (here we have taken 1 second time)
try{
Thread.sleep(1000);
}catch(Exception e){}

ticketsAvailable--;
System.out.println("Ticket BOOKED for : "+ Thread.currentThread().getName());
System.out.println("currently ticketsAvailable = "+ticketsAvailable);
}
else{
System.out.println("Ticket NOT BOOKED for : "+
Thread.currentThread().getName());
}

}//End synchronization block

}
public class MyClass {
public static void main(String args[])
{
TicketBooking obj=new TicketBooking();
Thread thread1=new Thread(obj,"Passenger1 Thread");
Thread thread2=new Thread(obj,"Passenger2 Thread");

thread1.start();
thread2.start();

}
}
/*OUTPUT
Waiting to book ticket for : Passenger2 Thread
Waiting to book ticket for : Passenger1 Thread
Booking ticket for : Passenger2 Thread
Ticket BOOKED for : Passenger2 Thread
currently ticketsAvailable = 0
Ticket NOT BOOKED for : Passenger1 Thread
*/
If we note the above program,
first Passenger1 Thread and Passenger2 Thread waited to book tickets.
Than, Passenger1 Thread entered the synchronized block and acquired object lock, but Passenger2 Thread wasn’t able to
acquire object lock and was waiting for Passenger1 Thread to release object lock.
By the time Passenger1 Thread was successfully able to book ticket and reduce the available ticket count to 0, and then
release object lock by exiting synchronized block.
Than Passenger2 Thread got a chance to acquire object lock, but available ticket count at that time was 0 so it wasn’t able
to book ticket.

RACE CONDITION PROBLEM SOLVED : 1 ticket was booked by only 1 passenger, while other wasn’t able to
book any ticket.

How threads communicate between each other?


This is very must know question for all the interviewees, you will most probably face this question in almost every time you
go for interview.
Threads can communicate with each other by using wait(), notify() and notifyAll() methods.

Definition and 8 key features >

 Definitions :
notify() - Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of
them is chosen to be awakened. The choice is random and occurs at the discretion of the implementation. A thread waits on
an object's monitor by calling one of the wait methods.

The awakened threads will not be able to proceed until the current thread relinquishes the lock on this object.

notifyAll() - Wakes up all threads that are waiting on this object's monitor. A thread waits on an object's monitor
by calling one of the wait methods.
The awakened threads will not be able to proceed until the current thread relinquishes the lock on this object.

wait() - Causes the current thread to wait until another thread invokes the notify() or notifyAll() method for this
object.
The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another
thread notifies threads waiting on this object's monitor to wake up either through a call to the notify()/ notifyAll() method.
The thread then waits until it can re-obtain ownership of the monitor and resumes execution.

 Thread state :
>By calling wait() method thread go from running to waiting state. In waiting state it will wait for other threads
to release object monitor/lock.
> Once notify() or notifyAll() method is called object monitor/lock becomes available and thread can again return to
runnable state.

 synchronized block : thread needs to to acquire object lock before calling wait() and notify() methods i.e. these
methods can be called only from synchronized block or synchronized method.
 Exception : As mentioned above before calling these methods thread must own object’s monitor means wait() and
notify() methods must be called from synchronized blocks or synchronized method otherwise IllegalMonitorStateException
is thrown at runtime.

 Waiting time : wait() and notify() method have got few options.
1. wait() - It internally calls wait(0).

2. wait(long timeout) - Causes the current thread to wait until either another thread invokes the notify() or
notifyAll() methods for this object, or a specified timeout time has elapsed.

public final native void wait(long timeout) throws InterruptedException;

3. wait(long timeout, int nanos) - Causes the current thread to wait until either another thread invokes the
notify() or notifyAll() methods for this object, or a specified timeout time plus the specified number of
nanoseconds has elapsed.

public static native void wait(long timeout,int nanos) throws InterruptedException;

notify() and notifyAll()


public final native void notify();
public final native void notifyAll();

 Instance methods : wait() and notify() are instance methods and are always called on objects.
 Native methods : implementation of wait() and notify() methods are provided by JVM.
Let’s see definition of wait() and notify() method as given in java.lang.Object -
public final void wait() throws InterruptedException

public final native void notify();


public final native void notifyAll();

 Belongs to which class : wait() and notify() methods belongs to java.lang.Object class.
Below i tried to give a very simple example to show usgae of wait() and notify() method to give you better understanding of
these methods.

Solve Consumer Producer problem by using wait() and notify() methods, where consumer can consume only when
production is over.
Producer will allow consumer to consume only when 10 products have been produced (i.e. when production is over).

Thought, we can solve this producer consumer problem without using wait() and notify() method as well, below i have
given consequences of not using using wait() and notify().

In program consumer thread will start() and wait by calling wait() method till producer is producing. Once
production is over, producer thread will call notify() method, which will notify consumer thread and consumer will
start consuming.
import java.util.ArrayList;
/* Producer is producing, Producer will allow consumer to
* consume only when 10 products have been produced (i.e. when production is over).
*/
class Producer implements Runnable{
ArrayList<Integer> sharedQueue;
Producer(){
sharedQueue=new ArrayList<Integer>();
}

@Override
public void run(){

synchronized (this) {
for(int i=1;i<=10;i++){ //Producer will produce 10 products
sharedQueue.add(i);
System.out.println("Producer is still Producing, Produced : "+i);

try{
Thread.sleep(1000);
}catch(InterruptedException e){e.printStackTrace();}

}
System.out.println("Production is over, consumer can consume.");
this.notify(); //Production is over, notify consumer thread so that consumer can consume.
}
}

}
class Consumer extends Thread{
Producer prod;

Consumer(Producer obj){
prod=obj;
}

public void run(){


/*
* consumer will wait till producer is producing.
*/
synchronized (this.prod) {

System.out.println("Consumer waiting for production to get over.");


try{
this.prod.wait();
}catch(InterruptedException e){e.printStackTrace();}

/*production is over, consumer will start consuming.*/


int productSize=this.prod.sharedQueue.size();
for(int i=0;i<productSize;i++)
System.out.println("Consumed : "+ this.prod.sharedQueue.remove(0) +" ");

}
public class ProducerConsumerWithWaitNotify {
public static void main(String args[]) throws InterruptedException{

Producer prod=new Producer();


Consumer cons=new Consumer(prod);

Thread prodThread=new Thread(prod,"prodThread");


Thread consThread=new Thread(cons,"consThread");

consThread.start(); //start consumer thread.


Thread.sleep(100); //This minor delay will ensure that consumer thread starts before producer thread.
prodThread.start(); //start producer thread.
}
}
/*OUTPUT
Consumer waiting for production to get over.
Producer is still Producing, Produced : 1
Producer is still Producing, Produced : 2
Producer is still Producing, Produced : 3
Producer is still Producing, Produced : 4
Producer is still Producing, Produced : 5
Producer is still Producing, Produced : 6
Producer is still Producing, Produced : 7
Producer is still Producing, Produced : 8
Producer is still Producing, Produced : 9
Producer is still Producing, Produced : 10
Production is over, consumer can consume.
Consumed : 1
Consumed : 2
Consumed : 3
Consumed : 4
Consumed : 5
Consumed : 6
Consumed : 7
Consumed : 8
Consumed : 9
Consumed : 10
*/

But what could be consequences of not using using wait() and notify() to solve above producer consumer problem?
It will cost of us performance. Consumer thread will unnecessarily repeatedly check whether producer has completed
it’s production or not, but when wait() and notify() were used, consumer thread started, called wait() and waited for
producer thread to notify.
Let’s identify Problem statement in not using wait() and notify()>
while(this.prod.productionInProcess)

Using while loop is the actual problem statement in not using wait() and notify(), loops generally costs us performance and
we must try to avoid loops.
Let’ say producer was to producer 100 products and for every production it takes 10 seconds & consumer is checking after
every 20seconds whether production is over or not. In that case consumer will check after every every 2 products produced
whether production is over or not, unnecessary 50 calls will be made, which will of course slow down our whole process.
But now, let's solve above problem without using wait() and notify() - approach which won’t be performance friendly (but
provides developers a choice to solve producer consumer problem in different manner).

In program producer thread will start() and it will start producing and called sleep(1000) in between, which will give
consumer thread chance to execute. consumer checks whether productionInProcess is true or not, if it's true,
consumer will sleep(4000) and wake up after specified time and again check whether productionInProcess is true or
false. process will repeat till productionInProcess is true. Meanwhile, producer thread will complete production and
ultimately make productionInProcess to false. Once productionInProcess is false, consumer will consume.

import java.util.ArrayList;
/* Producer is producing, Producer will allow consumer to
* consume only when 10 products have been produced (i.e. when production is over).
*/
class Producer implements Runnable{

boolean productionInProcess;
ArrayList<Integer> list;

Producer(){
productionInProcess=true; //initially Producer will be producing, so make this productionInProcess true.
list=new ArrayList<Integer>();
}
@Override
public void run(){

for(int i=1;i<=10;i++){ //Producer will produce 10 products


list.add(i);
System.out.println("Producer is still Producing, Produced : "+i);

try{
Thread.sleep(1000);
}catch(InterruptedException e){e.printStackTrace();}

}
productionInProcess=false; // Once production is over, make this productionInProcess false.
//Production is over, consumer can consume.

}
class Consumer extends Thread{
Producer prod;

Consumer(Producer obj){
prod=obj;
}

public void run(){


/*
* consumer checks whether productionInProcess is true or not, if it's true,
* consumer will sleep and wake up after certain time and again check whether productionInProcess is true or false.
* process will repeat till productionInProcess is true.
* Once productionInProcess is false we'll exit below while loop.
*/
while(this.prod.productionInProcess){ //costing us performance
System.out.println("Consumer waiting for production to get over.");
try{
Thread.sleep(4000);
}catch(InterruptedException e){e.printStackTrace();}

/*productionInProcess is false means production is over, consumer will start consuming. */


System.out.println("Production is over, consumer can consume.");
int productSize=this.prod.list.size();
for(int i=0;i<productSize;i++)
System.out.println("Consumed : "+ this.prod.list.remove(0) +" ");

}
public class ProducerConsumerWithoutWaitNotify {
public static void main(String args[]){

Producer prod=new Producer();


Consumer cons=new Consumer(prod);

Thread prodThread=new Thread(prod,"prodThread");


Thread consThread=new Thread(cons,"consThread");

prodThread.start(); //start producer thread.


consThread.start(); //start consumer thread.

}
}
/*OUTPUT
Consumer waiting for production to get over.
Producer is still Producing, Produced : 1
Producer is still Producing, Produced : 2
Producer is still Producing, Produced : 3
Producer is still Producing, Produced : 4
Producer is still Producing, Produced : 5
Producer is still Producing, Produced : 6
Producer is still Producing, Produced : 7
Producer is still Producing, Produced : 8
Producer is still Producing, Produced : 9
Producer is still Producing, Produced : 10
Production is over, consumer can consume.
Consumed : 1
Consumed : 2
Consumed : 3
Consumed : 4
Consumed : 5
Consumed : 6
Consumed : 7
Consumed : 8
Consumed : 9
Consumed : 10
*/

Why wait(), notify() and notifyAll() are in Object class and not in Thread class in java

1. Every Object has a monitor, acquiring that monitors allow thread to hold lock on object. But Thread class does not
have any monitors.

2. wait(), notify() and notifyAll() are called on objects only > When wait() method is called on object by thread it
waits for another thread on that object to release object monitor by calling notify() or notifyAll() method on
that object.
When notify() method is called on object by thread it notifies all the threads which are waiting for that object monitor
that object monitor is available now.
So, this shows that wait(), notify() and notifyAll() are called on objects only.
3. Wait(), notify() and notifyAll() method being in Object class allows all the threads created on that object to
communicate with other. [As multiple threads may exist on same object].

4. As multiple threads exists on same object. Only one thread can hold object monitor at a time. As a result thread
can notify other threads of same object that lock is available now. But, thread having these methods does not make
any sense because multiple threads exists on object it's not other way around (i.e. multiple objects exists on
thread).

5. Now let’s discuss one hypothetical scenario, what will happen if Thread class contains wait(), notify() and
notifyAll() methods?
Having wait(), notify() and notifyAll() methods means Thread class also must have their monitor.
Every thread having their monitor will create few problems -
>Thread communication problem.
>Synchronization on object won’t be possible- Because object has monitor, one object can have multiple threads
and thread hold lock on object by holding object monitor. But if each thread will have monitor, we won’t have any way of
achieving synchronization.
>Inconsistency in state of object (because synchronization won't be possible).

Is it important to acquire object lock before calling wait(), notify() and notifyAll()?

Yes, it’s mandatory to acquire object lock before calling these methods on object. As discussed above wait(), notify() and
notifyAll() methods are always called from Synchronized block only, and as soon as thread enters synchronized block
it acquires object lock (by holding object monitor). If we call these methods without acquiring object lock i.e. from outside
synchronize block then java.lang. IllegalMonitorStateException is thrown at runtime.
Wait() method needs to enclosed in try-catch block, because it throws compile time exception i.e. InterruptedException.

How can you solve consumer producer problem by using wait() and notify() method? (Important)
Here come the time to answer very very important question from interview perspective. Interviewers tends to check how
sound you are in threads inter communication. Because for solving this problem we got to use synchronization blocks,
wait() and notify() method very cautiously. If you misplace synchronization block or any of the method, that may
cause your program to go horribly wrong. So, before going into this question first i’ll recommend you to understand how
to use synchronized blocks, wait() and notify() methods.

Solve Consumer Producer pattern by using wait() and notify() methods in multithreading in java
Here come the time to answer very very important question from interview perspective. Interviewers tends to check how
sound you are in threads inter communication. Because for solving this problem we got to use synchronization blocks,
wait() and notify() method very cautiously. If you misplace synchronization block or any of the method, that may
cause your program to go horribly wrong. So, before going into this question first i’ll recommend you to understand how
to use synchronized blocks, wait() and notify() methods.

Key points we need to ensure before programming :


>Producer will produce total of 10 products and cannot produce more than 2 products at a time until products are being
consumed by consumer.
Example> when sharedQueue’s size is 2, wait for consumer to consume (consumer will consume by calling
remove(0) method on sharedQueue and reduce sharedQueue’s size). As soon as size is less than 2, producer will start
producing.
>Consumer can consume only when there are some products to consume.
Example> when sharedQueue’s size is 0, wait for producer to produce (producer will produce by calling add()
method on sharedQueue and increase sharedQueue’s size). As soon as size is greater than 0, consumer will start consuming.

Explanation of Logic >


It’s important to know that sharedQueue is a queue implemented using Linked List.
We will create sharedQueue that will be shared amongst Producer and Consumer. We will now start consumer and producer
thread.
Note: it does not matter order in which threads are started (because rest of code has taken care of synchronization and key
points mentioned above)

First we will start consumerThread >

consumerThread.start();

consumerThread will enter run method and call consume() method. There it will check for sharedQueue’s size.
-if size is equal to 0 that means producer hasn’t produced any product, wait for producer to produce by using
below piece of code-

synchronized (sharedQueue) {
while (sharedQueue.size() == 0) {
sharedQueue.wait();
}
}

-if size is greater than 0, consumer will start consuming by using below piece of code.

synchronized (sharedQueue) {
Thread.sleep((long)(Math.random() * 2000));
System.out.println("consumed : "+ sharedQueue.remove(0));
sharedQueue.notify();
}

Than we will start producerThread >

producerThread.start();

producerThread will enter run method and call produce() method. There it will check for sharedQueue’s size.
-if size is equal to 2 (i.e. maximum number of products which sharedQueue can hold at a time), wait for consumer
to consume by using below piece of code-

synchronized (sharedQueue) {
while (sharedQueue.size() == maxSize) { //maxsize is 2
sharedQueue.wait();
}
}

-if size is less than 2, producer will start producing by using below piece of code.

synchronized (sharedQueue) {
System.out.println("Produced : " + i);
sharedQueue.add(i);
Thread.sleep((long)(Math.random() * 1000));
sharedQueue.notify();
}

Full Program/sourceCode to solve consumer producer problem using wait() and notify() method>
import java.util.LinkedList;
import java.util.List;
/**
* Producer Class.
*/
class Producer implements Runnable {
private List<Integer> sharedQueue;
private int maxSize=2; //maximum number of products which sharedQueue can hold at a time.
public Producer(List<Integer> sharedQueue) {
this.sharedQueue = sharedQueue;
}
@Override
public void run() {
for (int i = 1; i <= 10; i++) { //produce 10 products.
try {
produce(i);
} catch (InterruptedException e) { e.printStackTrace(); }
}
}
private void produce(int i) throws InterruptedException {

synchronized (sharedQueue) {
//if sharedQuey is full wait until consumer consumes.
while (sharedQueue.size() == maxSize) {
System.out.println("Queue is full, producerThread is waiting for "
+ "consumerThread to consume, sharedQueue's size= "+maxSize);
sharedQueue.wait();
}
}

/* 2 Synchronized blocks have been used means before


* producer produces by entering below synchronized
* block consumer can consume.
*/

//as soon as producer produces (by adding in sharedQueue) it notifies consumerThread.


synchronized (sharedQueue) {
System.out.println("Produced : " + i);
sharedQueue.add(i);
Thread.sleep((long)(Math.random() * 1000));
sharedQueue.notify();
}
}
}
/**
* Consumer Class.
*/
class Consumer implements Runnable {
private List<Integer> sharedQueue;
public Consumer(List<Integer> sharedQueue) {
this.sharedQueue = sharedQueue;
}

@Override
public void run() {
while (true) {
try {
consume();
Thread.sleep(100);
} catch (InterruptedException e) { e.printStackTrace(); }
}
}
private void consume() throws InterruptedException {

synchronized (sharedQueue) {
//if sharedQuey is empty wait until producer produces.
while (sharedQueue.size() == 0) {
System.out.println("Queue is empty, consumerThread is waiting for "
+ "producerThread to produce, sharedQueue's size= 0");
sharedQueue.wait();
}
}

/* 2 Synchronized blocks have been used means before


* consumer start consuming by entering below synchronized
* block producer can produce.
*/

/*If sharedQueue not empty consumer will consume


* (by removing from sharedQueue) and notify the producerThread.
*/
synchronized (sharedQueue) {
Thread.sleep((long)(Math.random() * 2000));
System.out.println("CONSUMED : "+ sharedQueue.remove(0));
sharedQueue.notify();
}
}

}
public class ProducerConsumerWaitNotify {
public static void main(String args[]) {
List<Integer> sharedQueue = new LinkedList<Integer>(); //Creating shared object

Producer producer=new Producer(sharedQueue);


Consumer consumer=new Consumer(sharedQueue);

Thread producerThread = new Thread(producer, "ProducerThread");


Thread consumerThread = new Thread(consumer, "ConsumerThread");
producerThread.start();
consumerThread.start();
}
}
/*OUTPUT
Queue is empty, consumerThread is waiting for producerThread to produce, sharedQueue's size= 0
Produced : 1
CONSUMED : 1
Produced : 2
CONSUMED : 2
Produced : 3
Produced : 4
CONSUMED : 3
Produced : 5
Queue is full, producerThread is waiting for consumerThread to consume, sharedQueue's size= 2
CONSUMED : 4
Produced : 6
Queue is full, producerThread is waiting for consumerThread to consume, sharedQueue's size= 2
CONSUMED : 5
Produced : 7
CONSUMED : 6
Produced : 8
Queue is full, producerThread is waiting for consumerThread to consume, sharedQueue's size= 2
CONSUMED : 7
Produced : 9
CONSUMED : 8
Produced : 10
CONSUMED : 9
CONSUMED : 10
Queue is empty, consumerThread is waiting for producerThread to produce, sharedQueue's size= 0
*/

How can you solve consumer producer pattern by using BlockingQueue? (Important)

Now it’s time to gear up to face question which is most probably going to be followed up by previous question i.e. after how
to solve consumer producer problem using wait() and notify() method. Generally you might wonder why interviewer's are so
much interested in asking about solving consumer producer problem using BlockingQueue, answer is they want to know
how strong knowledge you have about java concurrent Api’s, this Api use consumer producer pattern in very optimized
manner, BlockingQueue is designed is such a manner that it offer us the best performance.
BlockingQueue is a interface and we will use its implementation class LinkedBlockingQueue.

Key methods for solving consumer producer pattern are >

put(i); //used by producer to put/produce in sharedQueue.


take(); //used by consumer to take/consume from sharedQueue.

Solve Consumer Producer problem by using BlockingQueue in multithreading in java - Detailed explanation with
full program

In this thread concurrency tutorial we will learn how to Solve Consumer Producer problem by using BlockingQueue and
LinkedBlockingQueue in multithreading in java using example and program.

Now it’s time to gear up to face question which is most probably going to be followed up by previous question i.e. how to
solve consumer producer problem using wait() and notify() method in java. Generally you might wonder why interviewer's
are so much interested in asking this question, answer is they want to know how strong knowledge you have about java
concurrent Api’s, this Api use consumer producer pattern in very optimized manner, BlockingQueue is designed is such a
manner that it offer us the best performance in java.
BlockingQueue is a interface and we will use its implementation class LinkedBlockingQueue. In one my post i have
mentioned how to implement custom BlockingQueue and solving Producer Consumer pattern using Custom implementation
of BlockingQueue interface.

Key methods in BlockingQueue Api for solving consumer producer in java pattern are >

put(i); //used by producer to put/produce in sharedQueue.


take(); //used by consumer to take/consume from sharedQueue.

Example/ Full Program/sourceCode to solve consumer producer problem using custom BlockingQueue in java >

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
/**
* Producer Class in java.
*/
class Producer implements Runnable {
private final BlockingQueue<Integer> sharedQueue;
public Producer(BlockingQueue<Integer> sharedQueue) {
this.sharedQueue = sharedQueue;
}
@Override
public void run() {
for(int i=1; i<=10; i++){
try {
System.out.println("Produced : " + i);
//put/produce into sharedQueue.
sharedQueue.put(i);
} catch (InterruptedException ex) {

}
}
}
}
/**
* Consumer Class in java.
*/
class Consumer implements Runnable{
private BlockingQueue<Integer> sharedQueue;
public Consumer (BlockingQueue<Integer> sharedQueue) {
this.sharedQueue = sharedQueue;
}
@Override
public void run() {
while(true){
try {
//take/consume from sharedQueue.
System.out.println("CONSUMED : "+ sharedQueue.take());
} catch (InterruptedException ex) {

}
}
}
}
public class ProducerConsumerBlockingQueue {
public static void main(String args[]){

//Creating shared object


BlockingQueue<Integer> sharedQueue = new LinkedBlockingQueue<Integer>();

Producer producer=new Producer(sharedQueue);


Consumer consumer=new Consumer(sharedQueue);

Thread producerThread = new Thread(producer, "ProducerThread");


Thread consumerThread = new Thread(consumer, "ConsumerThread");
producerThread.start();
consumerThread.start();
}
}
/*OUTPUT
Produced : 1
Produced : 2
CONSUMED : 1
Produced : 3
CONSUMED : 2
Produced : 4
CONSUMED : 3
Produced : 5
CONSUMED : 4
Produced : 6
CONSUMED : 5
Produced : 7
CONSUMED : 6
Produced : 8
CONSUMED : 7
Produced : 9
CONSUMED : 8
Produced : 10
CONSUMED : 9
CONSUMED : 10
*/

SUMMARY >
So, in this thread concurrency tutorial we learned how to Solve Consumer Producer problem by using BlockingQueue
and LinkedBlockingQueue in multithreading in java.

Difference between String, StringBuffer and StringBuilder in java - In depth coverage

Difference between String, StringBuffer and StringBuilder is a very important interview question. It’s very
basic question which every developer must know.

Here I have covered few in depth differences as well which will be handy for experienced developers.

Difference between String, StringBuffer and StringBuilder in java - In depth coverage

Property String StringBuffer StringBuilder

1 Storage area When String is created without using new


operator, JVM will create string in string
pool area of heap.

When String is created using new operator,


it will force JVM to create new string in
heap (not in string pool).

Example -->
String s1 = "abc"; StringBuffer is StringBuilder is
> in string pool area of heap. created in heap. created in heap.

String s2 = new String("abc");


> in heap

2 mutable/ String is immutable class in java, any StringBuffer is StringBuilder is


Immutable changes made to Sting class produces new mutable class in mutable class in
String. java, any changes java, any changes
made to made to
StringBuffer StringBuilder class
class won’t won’t produces
Please see produces new new String.
example 1a and example 1b below. String.

Please see
example 2 Please see
below. example 3 below.

3 Thread-safe/ String is immutable that makes it a StringBuffer StringBuilder


Synchronized thread -safe class. methods are methods are not
synchronized. synchronized.

Means no 2 Means 2 threads on


threads on same same StringBuilder
StringBuffer object can access
object cannot methods
access methods concurrently.
concurrently.
Note : Methods of
StringBuffer and
StringBuilder are
same, the only
difference is of
synchronization.

4 Performance Value of String in String pool is cached, hence Because of Because of non
making it fast. synchronized synchronized
methods its slow. methods its fast.
String created with new operator is also fast
process.

5 Internal Let’s say we have following statements - Internally Internally


working String str = "abc" ; StringBuffer adds StringBuilder adds
str = str + "def"; new characters to new characters to
previous previous
Internally + operator uses StringBuffer for StringBuffer. StringBuilder.
concatenating strings.

So,
String str = new
StringBuilder(str).append("def").toString();

6 Introduced in Java 1 Java 1 Java 5


jdk 1.0 jdk 1.0 jdk 1.5

String mutable/ Immutable

Example 1a -->

String str= "ab";


> No string with “ab” is there in string pool, so JVM will create string “ab” in string pool and str will be a reference
variable which will refer to it.
str.concat("cd")
> cd will be concatenated with ab and new string “abcd” will be formed. No string with “abcd” is there in pool, so JVM
will create string “abcd” in string pool, but there won’t be any reference variable to “abcd” (we are just using it only in
syso statement), meanwhile str will still be pointing to “ab”.

System.out.println(str);
str is referring to “ab” and string “abcd” will be eligible for garbage collection.

String mutable/ Immutable

Example 1b -->
What will happen when below 2 statements will execute >

String str= "ab";


str = "abcd";

String str= "ab";


No string with “ab” is there in string pool, so JVM will create string “ab” in string pool and str will be a reference variable
which will refer to it.

str = "abcd";
Now, No string with “abcd” is there in string pool, so JVM will create new string “abcd” in string pool and str will be a
reference variable which will refer to it.

String "abcd" will stay in string pool but reference to it will be lost, and it will be eligible for garbage collection.

StringBuffer mutable/ Immutable

Example 2-->

StringBuffer sBuffer = new StringBuffer("ab") ;


>JVM will create stringBuffer object “ab” in heap and sBuffer will be a reference variable which will refer to it.

sBuffer= sBuffer.append("cd");
> “cd” will be added to StringBuffer object referred by sBuffer. So, “abcd” will be formed.

(Note: addition was made to previous object, no new object was formed,
Behaviour was different as compared to immutable String’s concat function
)

System.out. println (sBuffer);


sBuffer is referring to “abcd” .

StringBuilder mutable/ Immutable

Example 3-->

StringBuilder sBuilder = new StringBuilder("ab") ;

>JVM will create stringBuilder object “ab” in heap and sBuilder will be a reference variable which will refer to it.

sBuilder=sBuilder. append("cd");

> “cd” will be added to StringBuilder object referred by sBuilder. So, “abcd” will be formed.
(Note: addition was made to previous object, no new object was formed,
Behaviour was different as compared to immutable String’s concat function
)
System.out.println(sBuilder);

sBuilder is referring to “abcd” .

What is reflection in java? Have you ever used reflection directly or directly?

Reflection in java>
Reflection is used to load java classes at runtime. Frameworks like struts, spring and hibernate uses reflection for loading classes at
runtime.

Let’s understand step-by-step how Reflection program will work in java >

Step 1 > load 'ReflectionClass' at runtime, please ensure you write package name before class name.
Step 2 > create object of ReflectionClass by calling constructor of ReflectionClass
Step 3 > calling methodNoPara() method of ReflectionClass.

Let’s create simple program to demonstrate concept of Reflection in java >


package reflection1;
import java.lang.reflect.Method;
class ReflectionClass {
/**
* constructor
*/
public ReflectionClass() {
System.out.println("in constructor of ReflectionClass");
}
/**
* Method with no parameter
*/
public void methodNoPara() {
System.out.println("in methodNoPara() of ReflectionClass ");
}
}
/**
* Main class
*/
public class ReflectionTest {
public static void main(String... a) {
try {
// step 1, load 'ReflectionClass' at runtime
Class cls = Class.forName("reflection1.ReflectionClass");
// step 2 //will call constructor of ReflectionClass
Object object = cls.newInstance();

// step 3, calling methodNoPara()


Method method = cls.getMethod("methodNoPara",
null);
method.invoke(object, null);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/*OUTPUT
in constructor of ReflectionClass
in methodNoPara() of ReflectionClass
*/

Exceptions thrown by methods used in reflection in java >

Method throws
Class.forName("reflection1.ReflectionClass" ClassNotFoundException
)

cls.newInstance() InstantiationException
IllegalAccessException

cls.getMethod("methodNoPara", null) SecurityException


NoSuchMethodException

Alternatively, for loading class we can use ClassLoader.getSystemClassLoader()>


Replace
Class.forName("reflection1.ReflectionClass");

with below code >


ClassLoader classLoader = ClassLoader.getSystemClassLoader();
Class cls = classLoader.loadClass("ReflectionClass");
Let’s create program to understand how we can pass String and Integer as argument in method in java>
package reflection2;
import java.lang.reflect.Method;
class ReflectionClass {
/**
* constructor
*/
public ReflectionClass() {
System.out.println("in constructor of ReflectionClass");
}
/**
* Method with no parameter
*/
public void methodNoPara() {
System.out.println("in methodNoPara() of ReflectionClass");
}
/**
* Method with String parameter
*/
public void methodString(String str) {
System.out.println("in methodString() > " + str);
}
/**
* Method with Integer parameter
*/
public void methodInteger(Integer integer) {
System.out.println("in methodInteger() > " + integer);
}
}
/**
* Main class
*/
public class ReflectionTest {
public static void main(String... a) {
try {
//String parameter
Class stringPara[] = new Class[1];
stringPara[0] = String.class;
Class integerPara[] = new Class[1];
integerPara[0] = Integer.class;

// step 1, load 'ReflectionClass' at runtime


Class cls =
Class.forName("reflection2.ReflectionClass");

// step 2 //will call constructor of ReflectionClass


Object object = cls.newInstance();

// step 3a, calling methodNoPara()


Method method = cls.getMethod("methodNoPara", null);
method.invoke(object, null);
// step 3b, calling methodString()
method = cls.getMethod("methodString", stringPara);
method.invoke(object, "ankit");
// step 3c, calling methodInteger()
method = cls.getMethod("methodInteger", integerPara);
method.invoke(object, 911);

} catch (Exception e) {
e.printStackTrace();
}
}
}
/*OUTPUT
in constructor of ReflectionClass
in methodNoPara() of ReflectionClass
in methodString() > ankit
in methodInteger() > 911
*/

What is significance of static in java?

1. The static is a keyword in java.


2. Static variable, method, class are stored in perm gen(permanent generation memory).
Static variable
3. static variables are also known as class variables.
4. We need not to create instance of class for accessing static variables.
Static method
5. static methods are also known as class methods.
6. We need not to create instance of class for accessing static methods.
Static class
7. static class are also known as static nested class.
8. Top level class can never be static in java.
Static block
9. static blocks are also known as static initialization blocks in java.
10. They are called as soon as class is loaded even before instance of class is created (i.e. before constructor is called).

Static keyword in java - variable, method, class, block - 25 salient features - Differences between static and instance/non-static
variable, methods, block and nested class

Static in java >


The static is a keyword in java.
Static can be used with following in java >
 1) variable
 2) method
 3) static class
 4 block
Where does static variable, method, class are stored in memory?
Static variable, method, class are stored in perm gen(permanent generation memory).

1) Static variable
 static variables are also known as class variables.
 We need not to create instance of class for accessing static variables
 static variables will remain same for different instance/objects of class but for every new object instance variables will be
initialized to new value.
 Static variables can be used inside constructor.
 Static variables are not serialized in java.
Diagram to where static variables are stored in memory & static variables remain same for different objects of class>
It's important to know that only the static variables and their values (primitives or references) are stored in PermGen space.
If static variable is a reference to an object that which is stored in the normal sections of the heap (string pool, young/old generation or
survivor space). Those objects are not stored in PermGen space.
Example code >
static int id = 1; //the value 1 is stored in the permgen area.
static Employee emp = new Employee (); //the reference(i.e. emp ) is
//stored in the permgen area, the object is not
static String company="XYZ pvt ltd"; //the reference(i.e. company)
is
//stored in the permgen area, but "XYZ pvt ltd" is not,
//"XYZ pvt ltd" gets stored in String pool.

Program to show value of static variables will remain same for different objects of class but for every new object instance variables will be
initialized to new value>
class Employee{
int id;
String name;
static String company="XYZ pvt ltd";

public Employee(int id, String name) {


this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + ", company=" + company + "]";
}
}
public class StaticVariableTest {
public static void main(String[] args) {
Employee emp1=new Employee(1, "ankit");
Employee emp2=new Employee(2, "sam");
System.out.println(emp1);
System.out.println(emp2);
}
}
/*OUTPUT
Employee [id=1, name=ankit, company=XYZ pvt ltd]
Employee [id=2, name=sam, company=XYZ pvt ltd]
*/
In the above program static variable was initialized at time of declaration, and its value will remain same for all instances of class, that’s
why they are also called as class variables.
Bad practice regarding accessing static variable>
Using instance.staticVariable is bad practice.
Example - emp1.company
You will face compiler warning=”The static field Employee.company should be accessed in a static way”
Resolution>
We must use ClassName.staticVariableName
Example - Employee.company

Difference between static and non-static variable>


Static variables Non-static variables

Known only as class variables. Also known as instance variables.

Static variables can be accessed inside > Non-static variables can be accessed inside >
static block, non-static block (instance block), non-static block (instance block),
static method, non-static method (instance method), non-static method (instance method),
methods of static nested class and inner class. methods of inner class.
in methods of static nested class.

Static variables are class variables access to them is always Non-Static variables are instance variables access to them is always
resolved during compile time. resolved during runtime.

Static variables are not serialized in java instance variables are serialized in java

2) Static method
 static methods are also known as class methods.
 We need not to create instance of class for accessing static methods.
 Static methods can access all static variables, but cannot access non-static (instance variables)
Important points about overriding static methods >
 Static method cannot be overridden, any attempt to do this will not cause compilation error.
 Static method cannot be overridden with non-static method, any attempt to do this will cause compilation error.
 Non-static method cannot be overridden with static method, any attempt to do this will cause compilation error.
Program for accessing static method>
public class StaticMethodTest{
public static void main(String[] args) {
staticMethod();
}
static void staticMethod() {
System.out.println("in staticMethod()");
}

}
/*OUTPUT
in staticMethod()
*/

About main method >


main method itself is static method, which is invoked by JVM, JVM does not create instance of class for accessing main method.
Bad practice regarding accessing static method>
Using instance.staticMethod() is bad practice.
You will face compiler warning=”The static method should be accessed in a static way”
Resolution>
We must use ClassName.staticMethod()
Difference between static and non-static ethod>
Static method Non-static method

Known only as class method. Also known as instance method.

Only static variables can be accessed inside static method Static and non-static variables (instance variables) can be accessed
inside static method.

We need not to create instance of class for accessing static methods. We need to create instance of class for accessing non-static
methods.

Static methods cannot be overridden. Non-static methods can be overridden.

Because static methods are class methods, access to them is always Because non static methods are instance methods, access to them is
resolved during compile time only using the compile time type always resolved during runtime time only using the runtime object.
information.

Static method cannot be overridden >


Its one of the favourite question of interviewers. Intention is to test few basic core java concepts.
Static method cannot be overridden, any attempt to do this will not cause compilation error, but the results won’t be same when we would
have overridden non-static methods.
But why?
Overriding in Java means that the method would be called on the run time based on type of the object and not on the compile time type of
it .
But static methods are class methods access to them is always resolved during compile time only using the compile time type information.
Accessing static method using object references is a bad practice (discussed above) and just an extra liberty given by the java designers.

EXAMPLE>
In below program access to SuperClass’s static method() is resolved during compile time only using the compile time type information (i.e.
by using SuperClass obj), means calling obj.method() is always going to invoke static method() of SuperClass.
Assign any sub type object to reference of superclass [obj=new SubClass()] won’t have any impact on call to static method at runtime.
Accessing static method using object references is bad practice (discussed above) and just an extra liberty given by the java designers.
Program to static method cannot be overridden>
class SuperClass{
static void method(){
System.out.println("superClass method");
}
}
class SubClass extends SuperClass{
static void method(){
System.out.println("SubClass method");
}
}
public class StaticMethodTest {

public static void main(String[] args) {


SuperClass obj=new SubClass();
obj.method();
}

}
/*OUTPUT
superClass method
*/

If non-static methods would have been used in above program, output would have been
subClass method

3) Static class
 static class are also known as
 static nested classes
 Top level class can never be static in java.
 Only static variables can be accessed inside static nested class.
 StaticNestedClass can be abstract or final.
 StaticNestedClass can be private, protected, public.
 strictfp modifier can also be used with StaticNestedClass.
 Static nested classes can declare static initialization blocks
 Static nested classes can declare member interfaces.
Note : Static nested class is not a inner class, its just a nested class.
Program for accessing static nested class>
class Employee{

//Inner class
class InnerClass {
public void method() {
System.out.println("In InnerClass's method");
}
}

//static nested class


static class StaticNestedClass{
public void method(){
System.out.println("In StaticNestedClass's method");
}
}
}
public class StaticClassTest {
public static void main(String[] args) {

//Accessing inner class


new Employee().new InnerClass().method();

//Accessing static nested class


new Employee . StaticNestedClass().method();
}

}
/*OUTPUT
In InnerClass's method
In StaticNestedClass's method
*/

Difference between static and non-static class>


Static class class (Non-static class)

Top level class can never be static in java. Top level class is always non static in java.

static class are also known as static nested classes. Top level class is just called as class .
But,
nested class is known as >
 inner class or
 member inner class.

Only Static member variables of outer class can be accessed inside Static and non-static member variables of outer class can be
methods of static nested class. accessed inside methods of non-static class

Accessing method of static nested class Accessing method of inner class

new OuterClass . StaticNestedClass().method(); new OuterClass().new InnerClass().method();

-Instance of top level class is not needed, we need to have instance Instance of top level class and InnerClass is needed.
of static nested class only

4) Static block / Static initialization block


 static blocks are called as soon as class is loaded even before instance of class is created (i.e. before constructor is called)
 static block are also known as static initialization blocks in java.
 Any code written inside static block is thread safe.
Difference between static and non-static block>
Static block Non-static blocks

Known as static initialization blocks. Also known as instance initialization blocks.

static blocks executes before instance blocks. instance blocks executes after static blocks.

Only static variables can be accessed inside static Static and non-static variables (instance variables) can be accessed inside instance
block block.

static blocks can be used for initializing static instance blocks can be used for initializing instance variables
variables or
or calling any instance method.
calling any static method.

static blocks executes when class is loaded. instance block executes only when instance of class is created, not called when class
is loaded.

this keyword cannot be used in static blocks. this keyword can be used in instance block.

Program to show static blocks are called as soon as class is loaded even before instance of class is created (i.e. before constructor is
called) >
class Employee {
/*
* Static block
*/
static {
System.out.println("static block");
}
/*
* Non-Static block (Instance block)
*/
{
System.out.println("non-static block");
}
/*
* Constructor
*/
Employee() {
System.out.println("Employee constructor");
}
}
public class StaticBlockTest {
public static void main(String[] args) {

//Create instance of Employee.


new Employee();

}
/*OUTPUT
static block
non-static block
Employee constructor
*/

Summary - 25 salient features of static keyword >

1. The static is a keyword in java.


2. Static variable, method, class are stored in perm gen(permanent generation memory).
Static variable
3. static variables are also known as class variables.
4. We need not to create instance of class for accessing static variables.
5. static variables will remain same for different instance/objects of class but for every new object instance variables will be
initialized to new value.
6. Static variables can be used inside constructor.
7. Static variables are not serialized in java
8. Its important to know that only the variables and their values (primitives or references) are stored in PermGen space.
If static variable is a reference to an object that which is stored in the normal sections of the heap (string pool, young/old generation or
survivor space). Those objects are not stored in PermGen space.
9. Using instance.staticVariable is bad practice, We must use ClassName.staticVariableName
Static method
10. static methods are also known as class methods.
11. We need not to create instance of class for accessing static methods.
12. Static methods can access all static variables, but cannot access non-static (instance variable
Important points about overriding static methods >
13. Static method cannot be overridden, any attempt to do this will not cause compilation error.
14. Static method cannot be overridden with non-static method, any attempt to do this will cause compilation error.
15. Non-static method cannot be overridden with static method, any attempt to do this will cause compilation error.
Static class
16. static class are also known as
o static nested classes

17. Top level class can never be static in java.


18. Only static variables can be accessed inside static class.

Static block
19. static blocks are also known as static initialization blocks in java.
20. static blocks executes as soon as class is loaded even before instance of class is created (i.e. before constructor is called).
21. static blocks executes before instance blocks.
22. Any code written inside static block is thread safe.
23. Only static variables can be accessed inside static block
24. static blocks can be used for initializing static variables or calling any static method.
25. this keyword cannot be used in static blocks.
Q65. Can we override static method in java?
Its one of the favourite question of interviewers. Intention is to test very basic core java concept.
Static method cannot be overridden, any attempt to do this will not cause compilation error, but the results won’t be same
when we would have overridden non-static methods.
But why?
Overriding in Java means that the method would be called on the run time based on type of the object and not on the compile
time type of it .

But static methods are class methods access to them is always resolved during compile time only using the compile time type
information.

Why Static method cannot be overridden in java - Explanation with program

It's one of the favourite question of interviewers. Intention is to test few basic core java concepts.
Static method cannot be overridden in java, any attempt to do this will not cause compilation error, but the results won’t be same when
we would have overridden non-static methods.
But why?
Overriding in Java means that the method would be called on the run time based on type of the object and not on the compile time type of it
But static methods are class methods access to them is always resolved during compile time only using the compile time type information.
Accessing static method using object references is a bad practice (we must access static variable using Class Name) and just an extra liberty
given by the java designers.

EXAMPLE>
In below program access to SuperClass’s static method() is resolved during compile time only using the compile time type information (i.e.
by using SuperClass obj), means calling obj.method() is always going to invoke static method() of SuperClass.
Assign any sub type object to reference of superclass [obj=new SubClass()] won’t have any impact on call to static method at runtime.
Accessing static method using object references is bad practice (discussed above) and just an extra liberty given by the java designers.

Program to static method cannot be overridden in java>


class SuperClass{
static void method(){
System.out.println("superClass method");
}
}
class SubClass extends SuperClass{
static void method(){
System.out.println("SubClass method");
}
}
/** Copyright (c), AnkitMittal JavaMadeSoEasy.com */
public class StaticMethodTest {

public static void main(String[] args) {


SuperClass obj=new SubClass();
obj.method();
}

}
/*OUTPUT
superClass method
*/

If non-static methods would have been used in above program, output would have been
subClass method

Important points you must know about overriding static methods in java >

 Static method cannot be overridden, any attempt to do this will not cause compilation error. (Discussed above)
 Static method cannot be overridden with non-static method, any attempt to do this will cause compilation error.
 Non-static method cannot be overridden with static method, any attempt to do this will cause compilation error.
How do you ensure different thread access different resources concurrently without deadlock?
Acquire lock on resources in a particular order and then releasing acquired lock in reverse order won’t create any deadlock.

Which method is called for garbage collection in java? What algorithm does garbage collector follows?
JVM calls finalize method on object for garbage collection

JVM follows mark and sweep algorithm for garbage collection.


Mark and sweep algorithm internal working in 3 steps >
STEP 1 > Unreferenced objects (garbage) are not reclaimed immediately.
 Instead, garbage(unreferenced objects) is gathered until memory is not full.
STEP 2 >When memory becomes full >
 execution of the program is suspended temporarily,
 mark and sweep algorithm collects all the garbage (i.e. all unreferenced objects are reclaimed )
STEP 3 >Once garbage is collected >
 execution of the program is resumed.

Why finalize method is protected in java - An explanation with programs


finalize method for object can be called from some other class outside the package with inheritance

SuperClass is in package com.ankit1


package com.ankit1;
public class SuperClass {
@Override
protected void finalize() throws Throwable {
try {
System.out.println("in finalize() method of SuperClass, "
+ "doing cleanup activity SuperClass");
} catch (Throwable throwable) {
throw throwable;
}
}
}

SubClass is in package com.ankit2


package com.ankit2;
import com.ankit1.SuperClass;
public class Subclass extends SuperClass{
@Override
protected void finalize() throws Throwable {
try {
System.out.println("in finalize() method of Subclass, "
+ "doing cleanup activity of Subclass");
} catch (Throwable throwable) {
throw throwable;
}finally{
super.finalize();
}
}
public static void main(String[] args) {
Subclass subclass = new Subclass();
System.out.println("in main() method");
try {
subclass.finalize(); //call finalize() method explicitly
} catch (Throwable throwable) {
throwable.printStackTrace();
}

}
}
/*OUTPUT
in main() method
in finalize() method of Subclass, doing cleanup activity of Subclass
in finalize() method of SuperClass, doing cleanup activity SuperClass
*/

Subclass extends SuperClass. So, calling super.finalize() is valid because finalize method for object can be called from some other class
outside the package with inheritance.
finalize method for object can’t be called from some other class outside the package without inheritance
MyClass1 is in package com.ankit1
package com.ankit1;
public class MyClass1 {
@Override
protected void finalize() throws Throwable {
//....
}
}
MyClass2 is in package com.ankit2

MyClass1 does not extends MyClass2. So, calling finalize() method by creating instance of MyClass1 in MyClass2 is invalid (any attempt
to do so will cause compilation error) because finalize method for object can’t be called from some other class outside the package
without inheritance.

Singleton in java, Doubly Locked Singleton class/ Lazy initialization, enum singleton, eager initialization in static block

Singleton class in java?


Singleton class means only one instance of class can exist.

1) Creating Singleton class in java>


creating INSTANCE variable -
Make it private > So that INSTANCE variable cannot be accessed outside class.
Make it static > So that INSTANCE variable can be accessed in static methods of class.
Make it Singleton type> So that INSTANCE variable can be refer to Singleton object.
creating private constructor-
Make it private > so that class can't be instantiated outside this class.

creating getInstance method -


Method which will return instance (only instance) of Singleton class.
Method will perform double check and ensure no two threads form more than one instance.

Method is public so that it could be accessed outside class.


Method is static so that it could be accessed without creating instance of class.

Use synchronized block inside method-so that 2 threads don’t create more than 1 instance of class concurrently.
This is also known as lazy initialization.

Program to create Singleton class/ Lazy initialization in java>

/**
* Singleton class - with Double checked Locking
*/
class Singleton {
//private > So that INSTANCE variable cannot be accessed outside class.
//static > So that INSTANCE variable can be accessed in static methods of class.
private static Singleton INSTANCE;
/**
* private constructor - so that class can't be instantiated outside this
* class
*/
private Singleton() {
}
/**
* Method which will return instance (only instance) of Singleton class.
*
* Method will perform double check and ensure no two threads form more than one
instance.
*
* Method is public so that it could be accessed outside class.
*
* Method is static so that it could be accessed without creating instance of class.
*
* Use synchronized block inside method-so that 2 threads don’t create more
* than 1 instance of class concurrently.
*/
public static Singleton getInstance() {
synchronized (Singleton.class) {
if (INSTANCE == null)
INSTANCE = new Singleton();
return INSTANCE;
}
}
/**
* instance method of Singleton class.
*/
public void m() {
System.out.println("m()");
}
}
/**
* Main class
*/
public class SingletonClassTest {
public static void main(String... a) {

//obj1 will be the reference variable to Singleton instance.


Singleton obj1 = Singleton.getInstance();
obj1.m();

//Let's conduct test to ensure instance return by


//Singleton are same

//obj2 will be the reference variable to Singleton instance.


Singleton obj2 = Singleton.getInstance();
obj2.m();

//Now, let's do equality test using == operator.


System.out.println(obj1==obj2); //True

}
}
/*OUTPUT
m()
m()
true
*/

In the later part of program we conducted test to ensure instance return by Singleton class are same.
First we obtained 2 references i.e. obj1 and obj2 to instance of Singleton class returned by getInstance() method.
Then equality test was done using == operator.
obj1==obj2 returned True, means two references are referring to same instance of class.

2) Program to create Doubly Locked Singleton class/ Lazy initialization in java>


/**
* Singleton class - with Double checked Locking
*/
class SingletonDoublyLocked {
private static SingletonDoublyLocked INSTANCE;
/**
* private constructor
*/
private SingletonDoublyLocked() {
}
public static SingletonDoublyLocked getInstance() {
//First check - To avoid more than one instance creation of Singleton
class.
if (INSTANCE == null) {
synchronized (SingletonDoublyLocked.class) {
//Second check - To avoid more than one instance creation of
//Singleton class.
if (INSTANCE == null) {
INSTANCE = new SingletonDoublyLocked();
}
}
}
return INSTANCE;
}

Let’s discuss in detail about logic of Doubly Locked Singleton class>


1. if (INSTANCE == null) {
2. synchronized (SingletonDoublyLocked.class) {
3. if (INSTANCE == null) {
4. INSTANCE = new SingletonDoublyLocked();
5. }
6. }
Let's say there are two threads t1 and t2 .
Let’s say t1 enters synchronized block reaches line 3, now t2 can’t reach line3 until t1 don’t leave synchronized block. By the time t1 must
be waiting at line 2 after (INSTANCE == null) returned true at line 1.
Before leaving synchronized block t1 must have instantiated INSTANCE at line 4. After t1 leaves synchronization block, t2 will enter
synchronized block and (INSTANCE == null) at line4 will return false because t1 already instantiated INSTANCE.

Understanding one more important concept >


At this point of time, i guess there might be one question in your mind.
Ques. Is if (INSTANCE == null) at line 1 is really needed?
Ans. If an instance of singleton class has already been created, then avoid double checked locking.

3) Creating Enum Singleton class in java>


 Singleton enum - Are best way to create Singleton
 Singleton enum are also thread safe.

Steps >
declare enum.
create private constructor.
Program to create Enum Singleton class>
/*
* Singleton enum - Are best way to create Singleton
* They are also thread safe.
*/
enum SingletonEnum {
SINGLETON_INSTANCE;
/** private constructor of enum. */
private SingletonEnum(){}
}
public class SingletonClassEnumTest {
public static void main(String...a){

System.out.println(SingletonEnum.SINGLETON_INSTANCE);

//Let's conduct test to ensure instance return by SingletonEnum are same


System.out.println(SingletonEnum.SINGLETON_INSTANCE==SingletonEnum.SINGLETON_INSTANCE);
//true

}
}
/*OUTPUT
SINGLETON_INSTANCE
true
*/

4) Singleton eager initialization in java>


Creating INSTANCE variable
Make it private > So that INSTANCE variable cannot be accessed outside class.
Make it static > So that INSTANCE variable can be accessed in static methods of class.
Make it final > Once initialized can’t be re initialized.
Make it Singleton type> So that INSTANCE variable can be refer to Singleton object.

creating private constructor-


Make it private > so that class can't be instantiated outside this class.

creating getInstance method -


Method which will return instance (only instance) of Singleton class.

class Singleton {
private static final Singleton INSTANCE=new Singleton();
/**
* private constructor - so that class can't be instantiated outside this
* class
*/
private Singleton(){
}
public static Singleton getInstance() {
return INSTANCE;
}
}

5) Singleton eager initialization in static block in java>

creating static block


 static blocks are called as soon as class is loaded even before instance of class is created(i.e. before constructor is called)
 Any code written inside static block is thread safe.

creating INSTANCE variable


Make it private > So that INSTANCE variable cannot be accessed outside class.
Make it static > So that INSTANCE variable can be accessed in static methods of class.
Make it Singleton type> So that INSTANCE variable can be refer to Singleton object.

creating private constructor-


Make it private > so that class can't be instantiated outside this class.

creating getInstance method -


Method which will return instance (only instance) of Singleton class.

class Singleton {
private static Singleton INSTANCE;

static{
INSTANCE=new Singleton();
}
/**
* private constructor - so that class can't be instantiated outside this
* class
*/
private Singleton() {
}
public static Singleton getInstance() {
return INSTANCE;
}
}

java is CALL BY VALUE (Pass by value) - NOT call by reference - With examples in java
In this core java tutorial we will learn in lots of detail that java is purely Pass by value and not Pass by reference with example, programs
and diagrams.

In java, arguments are passed by value (call by value/ Pass by value) only.
Java does not passes value by reference (call by reference/ Pass by reference).

First I will like to discuss what is difference between call by value and call by reference. And what happens in call by value and reference in

java. Does object changes or not in java?

So, let’s start with Call by value.

Question : What is Call by value (Pass by value)? And how java is call by value?

Answer : Call by value means Copy of an argument is passed to method. Therefore, any changes made to the argument in passed method

won’t change the value of original argument.

In java when any changes are made to the argument in passed method the value of original argument is not changed. Hence, Java is

call by value.

Now, let’s move to Call by reference.

Question : What is Call by reference (Pass by reference)? And what happens in Call by reference? And how java is NOT call by

reference?

Answer : In Call by reference, reference of argument is passed to method. Therefore, any changes made to the argument in passed

method will change the value of original argument as well.

In java when any changes are made to the argument in passed method the value of original argument is not changed. Hence, Java is

NOT call by reference.

Program 1 - to demonstrate Call by value (Pass by value) in java


In this example first we assigned some value to int i and String str, then passed them to method m(),
then we made some changes to i and str in method m()
Then we printed i and str in main method but changes were not reflected in main method. So, that shows java passed value by copy in
java.

public class PassByValueExample1 {


public static void main(String[] args) {

int i=1; //primitive type


String str = "a"; //String object

System.out.println("In main(), BEFORE passing by value i.e. BEFORE calling method


m()");
System.out.println("i = "+i+", str = "+str);

m(i, str); //PASS int primitive type and String object by VALUE

System.out.println("\nIn main(), AFTER passing by value i.e. AFTER calling method m()");
System.out.println("i = "+i+", str = "+str);

}
static void m(int i, String str){
i = 2;
str = "b";
System.out.println("\nIn method m(), after making changes to parameters");
System.out.println("i = "+i+", str = "+str);

}
}
/*OUTPUT
In main(), BEFORE passing by value i.e. BEFORE calling method m()
i = 1, str = a
In method m(), after making changes to parameters
i = 2, str = b
In main(), AFTER passing by value i.e. AFTER calling method m()
i = 1, str = a
*/
Now, let’s analyze about call by value example - In above example Copy of an argument is passed to method m() and therefore any

changes made to the argument in passed method i.e. m() didn’t change the value of original argument. in java

Program 2 - to demonstrate Call by value (Pass by value) - reference to object is passed by copy in java

Before reading below text I will like you to be careful about the terms in which reference is used. Do not mess up between reference to

object and call by reference in java.

Reference to object is passed by value (i.e. copy of reference is created and passed), reference to object is not at all passed by reference

in java.

Here in the below program, a is reference to object Emp a is passed by value (i.e. copy of a is created and passed), a is not at all passed

by reference, it may look like that a is passed by reference but actually that doesn't happens at all copy of a is created and that is passed to

method m() in java.

class Emp{
int id;
public Emp(int id) {
this.id = id;
}
}
public class PassByValueExample2 {
public static void main(String[] args) {
Emp a=new Emp(1);

System.out.println("In main(), BEFORE passing a by value i.e. BEFORE calling method


m()");
System.out.println("a.id = "+a.id);

m(a); //Here a is reference to object Emp


// a is passed by value (i.e. copy of a is created and passed),
//a is not at all passed by reference,
//it may look like that a is passed by reference but actually that doesn't happens at all
//copy of a is created and that is passed to method m()
System.out.println("\nIn main(), AFTER passing a by value i.e. AFTER calling method m()");
System.out.println("a.id = "+a.id);

}
static void m(Emp b){
b.id = 2;
System.out.println("\nIn method m(), after making some changes");
System.out.println("b.id = " + b.id);
}
}
/*OUTPUT
In main(), BEFORE passing a by value i.e. BEFORE calling method m()
a.id = 1
In method m(), after making some changes
b.id = 2
In main(), AFTER passing a by value i.e. AFTER calling method m()
a.id = 2
*/
So, we can say that reference to object is passed by copy in java.

2.1) Let’s understand by diagram how in above program (program 2) reference to object is passed by copy in java >

Emp a=new Emp(1);


A is declared as reference to object Emp.

static void m(Emp b)


In the method m(), Emp b is declared, b is assigned to null.

m(a);
When method m is called, a is also passed to method m, but a is not directly passed to method m(), first copy of a is created and then passed
to method m.

b.id = 2;
b.id is assigned a new value, a and b are referring to same object so any changes made to b will be reflected in a as well.

We cannot change the reference in the called method i.e. the method in which reference to the object has been passed by copy, If in

case reference is changed in called method, the copy of reference in the called method will start pointing to the new object but

original reference will keep on pointing to old object only in java. We will understand this in next program.

Program 3 - In continuation to program 2 - to demonstrate Call by value (Pass by value) - reference to object is passed by copy in java

Reference to object is passed by value (i.e. copy of reference is created and passed), reference to object is not at all passed by reference.

Here in the below program, a is reference to object Emp, a is passed by value (i.e. copy of a is created and passed), a is not at all passed

by reference, it may look like that a is passed by reference but actually that doesn't happens at all copy of a is created and that is passed to

method m() in java.

We cannot change the reference b in the method m(), if in case, b is changed, b will start pointing to the new object but original

reference i.e. a will keep on pointing to old object only in java.

class Emp{
int id;
public Emp(int id) {
this.id = id;
}
}
public class PassByValueExample3 {
public static void main(String[] args) {
Emp a=new Emp(1);

System.out.println("In main(), BEFORE passing a by value i.e. BEFORE calling method


m()");
System.out.println("a.id = "+a.id);

m(a); //Here a is reference to object Emp


// a is passed by value (i.e. copy of a is created and passed),
//a is not at all passed by reference,
//it may look like that a is passed by reference but actually that doesn't happens at all
//copy of a is created and that is passed to method m()
System.out.println("\nIn main(), AFTER passing a by value i.e. AFTER calling method m()");
System.out.println("a.id = "+a.id);

}
static void m(Emp b){
b = new Emp(2); //Now b will start pointing to newly created object
System.out.println("\nIn method m(), after making some changes");
System.out.println("b.id = " + b.id);
}
}
/*OUTPUT
In main(), BEFORE passing a by value i.e. BEFORE calling method m()
a.id = 1
In method m(), after making some changes
b.id = 2
In main(), AFTER passing a by value i.e. AFTER calling method m()
a.id = 1
*/

3.1) Let’s understand by diagram how in above program (program 3) reference to object is passed by copy in java >

Emp a=new Emp(1);


A is declared as reference to object Emp.

static void m(Emp b)


In the method m(), Emp b is declared, b is assigned to null.

m(a);
When method m is called, a is also passed to method m, but a is not directly passed to method m(), first copy of a is created and then passed
to method m.

b = new Emp(2);
b is assigned new Emp object. So, b will start pointing to the new object but original reference i.e. a will keep on pointing to old object only.

So, we can say that reference to object is passed by copy in java.

So in this core java tutorial we learned in lots of detail that java is purely Pass by value and not Pass by reference with example, programs
and diagrams.

Types of Inner classes with example - Inner class, static nested class, local and anonymous inner class in java, Difference between
static and non-static class

1) Inner class
 1.1) An inner class is a nested class that is not explicitly or implicitly declared static.
 1.2) Inner class is also known as
 member inner class.
 1.3) Inner class is considered as instance member variable of outer class.
 1.4) Inner class has access to all other member variables of outer class. Inner class can access -
 instance member variable of outer class
 instance methods of outer class
 static member variable of outer class
 static methods of outer class
 Outer class reference
 Inner class reference
 Inner class is instance specific/ object specific class. It has got access to this reference of outer class.
o Hence, can access OuterClass instance variable and instance method using OuterClass reference this.

 1.5) InnerClass can be declared private, protected, public.


 1.6) strictfp modifier can also be used with InnerClass.
 1.7) InnerClass can be abstract or final.
 1.8) Inner classes cannot declare static initialization blocks
 1.9) Inner classes cannot declare member interfaces.
 1.10) Inner classes can declare instance initialization blocks

class OuterClass{
//Inner class
class InnerClass {
//Inner classes cannot not declare static initialization
blocks
static{} //compilation error

//Inner classes cannot not declare member interfaces.


interface I{} //compilation error

//Inner classes can declare instance initialization blocks


{}

//Inner class constructor


InnerClass() {}
}
}

1.11) Inner classes cannot declare static members


1.12) Inner classes can declare constant variables
1.13) Inner classes can inherit static members that are not constant variables.

class A{

//Inner classes can inherit static members that are not constant
variables
static int x = 1;
}
class OuterClass {
// Inner class
class InnerClass extends A{

// Inner classes cannot not declare static members


static int i = 2; // compilation error

//Inner classes can declare constant variables


static final int j = 3; // Fine
}
}

1.14) Inner classes can be declared in abstract class.


1.15) Inner classes can be declared in interface.
Program for instantiating inner class and show what member variable of OuterClass can be accessed in inner class>
package com.ankit;
class OuterClass{
int i=1; //instanceVariable
void m(){} //instanceMethod
static int staticI=1; //staticVariable
static void staticM(){} //staticMethod
//Inner class
class InnerClass {
public void method() {
System.out.println("In InnerClass's method");

i=1; //OuterClass instanceVariable


m(); //OuterClass instanceMethod

staticI=1; //OuterClass staticVariable


staticM(); //OuterClass staticMethod

System.out.println("OuterClass reference="+OuterClass.this);
System.out.println("InnerClass reference="+this);

OuterClass.this.i=2;//Accessing OuterClass instanceVariable using OuerClass reference


OuterClass.this.m();//Accessing OuterClass instanceMethod using OuterClass
reference

}
} //End InnerClass
}
/**
* Main class
*/
public class InnerClassTest {
public static void main(String[] args) {

//Creating instance of InnerClass


new OuterClass().new InnerClass().method();

}
/*OUTPUT
In InnerClass's method
OuterClass reference=com.ankit.OuterClass@1a4eb98b
InnerClass reference=com.ankit.OuterClass$InnerClass@2677622b
*/

To create instance of the InnerClass we must create instance of OuterClass first.

When above program is compiled following .class files are formed >
OuterClass.class > OuterClass
OuterClass$InnerClass.class >InnerClass
InnerClassTest.class >InnerClassTest (Main class)

2) Static nested class

 2.1) Method of nested class can only be static if nested class is a static nested class.
 2.2) Static nested class is considered as static member variable of outer class.
 2.3) StaticNestedClass has access to all static member variables and static methods of OuterClass.
 2.4) StaticNestedClass can be abstract or final.
 2.5) StaticNestedClass can be private, protected, public.
 2.6) strictfp modifier can also be used with StaticNestedClass.

 2.7) Static nested classes can declare static initialization blocks


 2.8) Static nested classes can declare member interfaces.
 2.9) Static nested classes can declare static members
 2.10) Static nested classes can declare constant variables
 2.11) Static nested classes can inherit static members that are not constant variables.
 2.12) Static nested classes can declare instance initialization blocks

class OuterClass {
// StaticNestedClass
static class StaticNestedClass {
// StaticNestedClass can declare static initialization blocks
static {
}
// StaticNestedClass can declare member interfaces.
interface I {
}
// StaticNestedClass can declare static members
static int i = 2;
// StaticNestedClass can declare constant variables
static final int j = 3;

//StaticNestedClass classes can declare instance initialization


blocks
{}

//StaticNestedClass constructor
StaticNestedClass() {}

}
}

 2.13) Static nested classes cannot be declared in abstract class.


 2.14) Static nested classes cannot be declared in interface.

Program for accessing static nested class>


package com.ankit;
class OuterClass{
static int staticI=1; //staticVariable
static void staticM(){} //staticMethod

//static Nested class


static class StaticNestedClass {
public void method() {
System.out.println("In StaticNestedClass's method");

staticI=1; //OuterClass staticVariable


staticM(); //OuterClass staticMethod

//System.out.println("StaticNestedClass reference="+this); //allowed

}//End StaticNestedClass
}
/**
* Main class
*/
public class NestedClassTest {
public static void main(String[] args) {

//Accessing method of StaticNestedClass


new OuterClass . StaticNestedClass().method();

}
/*OUTPUT
In StaticNestedClass's method
*/

 To access method of the StaticNestedClass we need not to create instance of OuterClass.

Difference between static and non-static class>

Static class class (Non-static class)


Top level class can never be static in java. Top level class is always non static in java.

static class are also known as static nested classes. Top level class is just called as class .
But,
nested class is known as >
 inner class or
 member inner class.

Only Static member variables of outer class can be accessed inside Static and non-static member variables of outer class can be
methods of static nested class. accessed inside methods of non-static class

Accessing method of static nested class Accessing method of inner class

new OuterClass . StaticNestedClass().method(); new OuterClass().new InnerClass().method();

-Instance of top level class is not needed, we need to have instance Instance of top level class and InnerClass is needed.
of static nested class only

When above program is compiled following .class files are formed >
OuterClass.class > OuterClass
OuterClass$StaticNestedClass.class >StaticNestedClass
InnerClassTest.class >InnerClassTest (Main class)

Note : Static nested class is not a inner class, its just a nested class.

3) Local inner class


 3.1) LocalInnerClass can be accessed inside method in which it has been created.
 3.2) LocalInnerClass has access to all other member variables of OuterClass like InnerClass.
 3.3) LocalInnerClass can be abstract or final.
 3.4) LocalInnerClass can’t be static.
 3.5) LocalInnerClass can’t be private, protected, public.
 3.6) LocalInnerClass can be declared in Expressions, Statements, and Blocks.

class OuterClass{
//LocalInnerClass inside instance block
{
class A{}
}

//LocalInnerClass inside static block


static{
class A{}
}

void myMethod(){
//LocalInnerClass inside if statement
if(true){
class A{}
}

//LocalInnerClass inside for loop statement


for(int i=0;i<1;i++){
class A{}
}
}

 3.7) strictfp modifier can be used with LocalInnerClass .


 3.8) Local Inner class cannot access the non-final local variables but can access final local variables.

Program for accessing local inner class>


package com.ankit;
class OuterClass{
int i=1; //instanceVariable
static int staticI=1; //staticVariable

//Inside this method we'll declare local class.


void myMethod(){
//Local Inner class
class LocalInnerClass {
public void method() {
System.out.println("In LocalInnerClass's method");

i=1; //OuterClass instanceVariable


staticI=1; //OuterClass staticVariable

System.out.println("OuterClass reference="+OuterClass.this);
System.out.println("InnerClass reference="+this);

}
} //End LocalInnerClass

//Creating instance of LocalInnerClass


new LocalInnerClass().method();

}
/**
* Main class
*/
public class InnerClassTest {
public static void main(String[] args) {

//Creating instance of OuterClass


new OuterClass().myMethod();

}
/*OUTPUT
In LocalInnerClass's method
OuterClass reference=com.ankit.OuterClass@2677622b
InnerClass reference=com.ankit.OuterClass$1LocalInnerClass@67ce08c7
*/

When above program is compiled following .class files are formed >
OuterClass.class > OuterClass
OuterClass$1LocalInnerClass.class >LocalInnerClass
InnerClassTest.class >InnerClassTest (Main class)

4) Anonymous Inner Class

Meaning of Anonymous in english dictionary is unknown name.


In java, AnonymousInnerClass means class with no name.

Program 1 for creating and using AnonymousInnerClass - And understanding how AnonymousInnerClass extend class>

class OuterClass{
void m(){
System.out.println("m()");
}
}

public class InnerClassTest {


public static void main(String[] args) {

//Anonymous inner class


OuterClass obj=new OuterClass(){

//Override m() method of OuterClass


void m(){
System.out.println("overridden m()");
}
};

obj.m(); //calls overridden m()


}

}
/*OUTPUT
overridden m()
*/

What happened in above program was >


AnonymousInnerClass was created which extends OuterClass, m() method of OuterClass was overridden in AnonymousInnerClass.
Note : AnonymousInnerClass extends OuterClass, without explicit use of extends keyword.

When above program is compiled following .class files are formed >
OuterClass.class > OuterClass
InnerClassTest$1.class >AnonymousInnerClass
InnerClassTest.class >InnerClassTest (Main class)

Program 2 for understanding more about AnonymousInnerClass >


class OuterClass{
void m(){
System.out.println("m()");
}
}
/**
* Main class
*/
public class InnerClassTest {
public static void main(String[] args) {

//Anonymous inner class


new OuterClass(){

}.m();
}

}
/*OUTPUT
m()
*/

What happened in above program was >


AnonymousInnerClass was created which extends OuterClass, m() method of OuterClass was inherited in AnonymousInnerClass.
Note : AnonymousInnerClass extends OuterClass, without explicit use of extends keyword.

Program 3 to understand how AnonymousInnerClass implement interface>


AnonymousInnerClass cannot implement more than one interface. Let’s create a program >
interface MyInterface{
void m();
}
/**
* Main class
*/
public class InnerClassTest {
public static void main(String[] args) {

//Anonymous inner class


new MyInterface(){ //implementing interface
public void m(){ //Provide implementation of MyInterface's m()
method
System.out.println("implementation of MyInterface's m() method");
}
}.m();
}
}
/*OUTPUT
implementation of MyInterface's m() method
*/

Note : AnonymousInnerClass implements MyInterface, without explicit use of implements keyword.

Program 4 to understand how AnonymousInnerClass can implement more than 2 interfaces >
Though, AnonymousInnerClass can implement more than one interface in following way >
Let’s create MyInterface which will extend Runnable interface. Now, AnonymousInnerClass will implement 2 interfaces.
interface MyInterface extends Runnable{
void m();
}
/**
* Main class
*/
public class InnerClassTest {
public static void main(String[] args) {

//Anonymous inner class


new MyInterface(){ //implementing interface
@Override //Provide implementation of MyInterface's m() method
public void m(){
System.out.println("implementation of MyInterface's m()
method");
}
@Override //Provide implementation of Runnable's run() method
public void run() {
}
}.m();
}

}
/*OUTPUT
implementation of MyInterface's m() method
*/

Differences between Instance initialization block and Static initialization block in java - Features in detail with programs
What are Instance initialization block & Static initialization block in java

Instance initialization block in java can be used to initialize instance variables in java.
Static initialization block in java can be used to initialize static variables in java.

Features of static initialization block in java >


 Static blocks are also called Static initialization blocks in java.
 Static block executes when class is loaded in java.
 static blocks executes before instance blocks in java.
 Only static variables can be accessed inside static block in java
 static blocks can be used for initializing static variables or calling any static method in java.
 this keyword cannot be used in static block in java.

Features of instance initialization block in java >


 Instance blocks are also called instance initialization blocks in java
 Instance block executes when instance of class is created in java.
 Also known as non-static initialization block in java.
 instance blocks executes after static blocks in java.
 Static and non-static variables (instance variables) can be accessed inside instance block in java.
 instance blocks can be used for initializing instance variables or calling any instance method in java.
 this keyword can be used in instance block in java.

Program 1 to show instance initialization blocks executes after static initialization blocks in java>

class MyClass {

/* Static block */
static {
System.out.println("static block");
}
/* Non-Static block (Instance block) */
{
System.out.println("instance/non-static block");
}
/* Constructor */
MyClass() {
System.out.println("MyClass constructor");
}
}
public class BlockTest {
public static void main(String[] args) {

//Create instance of MyClass.


new MyClass();

}
/*OUTPUT
static block
instance/non-static block
MyClass constructor
*/

Program 2 to show execution flow of static initialization blocks and instance initialization blocks when SuperClass and SubClasses are

used in java>

/**
* SuperClass
*/
class SuperClass {

/* Static block */
static {
System.out.println("SuperClass ----------> static block");
}
/* Non-Static block (Instance block) */
{
System.out.println("SuperClass ----------> Instance/non-static
block");
}
/* Constructor*/
SuperClass() {
System.out.println("SuperClass ----------> constructor");
}
}
/**
* SubClass
*/
class SubClass extends SuperClass {

/* Static block */
static {
System.out.println("SubClass > static block");
}
/* Non-Static block (Instance block) */
{
System.out.println("SubClass > Instance/non-static block");
}
/* Constructor*/
SubClass() {
System.out.println("SubClass > constructor");
}
}
public class BlockTest {
public static void main(String[] args) {

//Create instance of SubClass.


new SubClass();

}
/*OUTPUT
SuperClass ----------> static block
SubClass > static block
SuperClass ----------> Instance/non-static block
SuperClass ----------> constructor
SubClass > Instance/non-static block
SubClass > constructor
*/

Difference between static initialization and instance initialization block in java>

Static block instance block

Known only as static initialization block in java. Also known as non-static initialization block in java.

static blocks executes before instance blocks in instance blocks executes after static blocks in java.
java.

Only static variables can be accessed inside Static and non-static variables (instance variables) can be accessed inside instance
static block block.

static blocks can be used for initializing static instance blocks can be used for initializing instance variables
variables or
or calling any instance method in java.
calling any static method in java.

static blocks executes when class is loaded in instance block executes only when instance of class is created, not called when class is
java. loaded in java.

this keyword cannot be used in static blocks. this keyword can be used in instance block.

Summary >
So in this core java tutorial we learned What are Instance initialization block & Static initialization block in java. Features of static
initialization block in java. Features of instance initialization block in java. Program to show instance initialization blocks executes
after static initialization blocks in java. Program to show execution flow of static initialization blocks and instance initialization
blocks when SuperClass and SubClasses are used in java. Difference between static initialization and instance initialization block in
java>

Q72. How ConcurrentHashMap works? Can 2 threads on same ConcurrentHashMap object access it concurrently ?
ConcurrentHashMap is divided into different segments based on concurrency level. So different threads can access different segments
concurrently.

Can threads read the segment locked by some other thread?


Yes. When thread locks one segment for updation it does not block it for retrieval (done by get method) hence some other thread can read
the segment (by get method), but it will be able to read the data before locking.

Segments in ConcurrentHashMap with diagram >


we have ConcurrentHashMap with 4 segments -
(Diagram shows how segments are formed in ConcurrentHashMap)
What is deadlock in multithreading? Write a program to form DeadLock in multi threading and also how
to solve DeadLock situation. What measures you should take to avoid deadlock? (Important)
This is very important question from interview perspective. But, what makes this question important is it checks interviewees
capability of creating and detecting deadlock. If you can write a code to form deadlock, than I am sure you must be well
capable in solving that deadlock as well. If not, later on this post we will learn how to solve deadlock as well.
Deadlock is a situation where two threads are waiting for each other to release lock
holded by them on resources.

What is life cycle of Thread, explain thread states? (Important)


Thread states/ Thread life cycle is very basic question, before going deep into concepts we must understand Thread life cycle.

Thread have following states >


 New
 Runnable
 Running
 Waiting/blocked/sleeping
 Terminated (Dead)

Thread life cycle in diagram >

What are daemon threads?


Daemon threads are low priority threads which runs intermittently in background for doing garbage
collection.

Differences and Similarities between HashMap and ConcurrentHashMap in java

16
Depending upon the level of concurrency required the concurrent HashMap is internally divided into segments. If the level of
concurrency required is not specified then it is takes 16 as the default value. So internally the ConcurrentHashMap will be divided into
16 segments. Each Segment behaves independently.

Property java.util.HashMap java.util.concurrent. ConcurrentHashMap


synchronization HashMap is not synchronized. ConcurrentHashMap is synchronized.

2 threads on Yes, because HashMap is not synchronized. Yes.


same Map object
can access it at But how despite of being synchronized, 2
concurrently? threads on same ConcurrentHashMap object
can access it at same time?

ConcurrentHashMap is divided into different


segments based on concurrency level. So
different threads can access different segments
concurrently.

Performance We will synchronize HashMap and then ConcurrentHashMap’s performance is


compare its performance with faster as compared to HashMap (because it
ConcurrentHashMap. is divided into segments, as discussed in above
point).
We can synchronize hashMap by using
Collections’s class synchronizedMap method.
Map synchronizedMap = SCROLL BELOW FOR PERFORMANCE
Collections.synchronizedMap(hashMap); COMPARISON WITH DIAGRAMS.

Now, no 2 threads can access same instance of


map concurrently.
Hence synchronized HashMap’s performance
is slower as compared to ConcurrentHashMap.

SCROLL BELOW FOR PERFORMANCE


COMPARISON WITH DIAGRAMS.

But why we didn’t compared HashMap


(unSynchronized) with ConcurrentHashMap?
Because performance of unSynchronized
collection is always better than some synchronized
collection. As, default (unSynchronized) hashMap
didn’t cause any locking.

Null keys and HashMap allows to store one null key and many ConcurrentHashMap does not allow to store
values null values i.e. any key can have null value. null key or null value.
Any attempt to store null key or value throws
runtimeException (NullPointerException).

iterators The iterators returned by the iterator() method of iterators are fail-safe.
HashMap are fail-fast >
hashMap.keySet().iterator() concurrentHashMap.keySet().iterator()
hashMap.values().iterator() concurrentHashMap.values().iterator()
hashMap.entrySet().iterator() concurrentHashMap.entrySet().iterator()

all three iterators are fail-fast all three iterators are fail-safe.

putIfAbsent HashMap does not contain putIfAbsent method. If map does not contain specified key, put
putIfAbsent method is equivalent to writing specified key-value pair in map and return
following code > null.
If map already contains specified key, return
synchronized (map){ value corresponding to specified key.
if (!map.containsKey(key))
return map.put(key, value);
else
return map.get(key);
}

Program to use ConcurrentHashMap’s


Program to create method that provides putIfAbsent method
functionality similar to putIfAbsent method of
ConcurrentHashMap and to be used with
HashMap

Introduced in HashMap was introduced in java 2 i.e. JDK 1.2, ConcurrentHashMap was introduced in java 5
which java i.e. JDK 1.5, since its introduction Hashtable
version has become obsolete, because of concurrency
level its performance is better than Hashtable.

Implements HashMap implements java.util.Map ConcurrentHashMap implements


which interface java.util.Map and
java.util.concurrent.ConcurrentMap

Package HashMap is in java.util package ConcurrentHashMap is in


java.util.concurrent package.

Performance comparison of java.util.concurrent.ConcurrentHashMap and java.util.HashMap in java >

ConcurrentHashMap is divided into different segments based on concurrency level. So different threads can access different
segments concurrently in java.

Can threads read the segment locked by some other thread?


Yes. When thread locks one segment for updation it does not block it for retrieval (done by get method) hence some other
thread can read the segment (by get method), but it will be able to read the data before locking in java.

For operations such as putAll concurrent retrievals may reflect removal of only some entries in java.
For operations such as clear concurrent retrievals may reflect removal of only some entries in java.

Segments in ConcurrentHashMap with diagram >


we have ConcurrentHashMap with 4 segments -
(Diagram shows how segments are formed in ConcurrentHashMap)

Now let’s form few questions to clear your doubts (based on above diagram) >

Question 1 : What will happen map.put(25,12) is called and some other thread concurrently calls map.get(25)?
Answer : When map.put(25,12) is called segment 2 will be locked,
key=25 also lies in segment 2, When thread locks one segment for updation it does not block it for retrieval hence some
other thread can read the same segment, but it will be able to read the data before locking (hence map.get(25) will return
121)

Question 2 : What will happen map.put(25,12) is called and some other thread concurrently calls map.get(33)?
Answer : When map.put(25,12) is called segment 2 will be locked,
key=33 also lies in segment 2, When thread locks one segment for updation it does not block it for retrieval hence some
other thread can read the same segment, but it will be able to read the data before locking (hence map.get(33) will return
15)
Question 3 : What will happen map.put(25,12) is called and some other thread concurrently calls map.put(33,24)?
Answer : When map.put(25,12) is called segment 2 will be locked,
key=33 also lies in segment 2, When thread locks one segment for updation it does not allow any other thread to perform
updations in same segment until lock is not released on segment.
hence map.put(33,24) will have to wait for map.put(25,12) operation to release lock on segment.

Question 4 : What will happen map.put(25,12) is called and some other thread concurrently calls map.put(30,29)?Answer :
When map.put(25,12) is called segment 2 will be locked, but key=30 lies in segment 3. Both the kays lies in different
segments, hence both operations can be performed concurrently.

Question 5 : What will happen updations (put/remove) are in process in certain segments and new key-pair have to be
put/remove in same segment ?
Answer : When updations are in process thread locks the segment and it does not allow any other thread to perform
updations (put/remove) in same segment until lock is not released on segment.
Let’s summarize above section >
What operations lock ConcurrentHashMap segment & what operations are allowed when ConcurrentHashMap segment is
locked >
 thread locks one segment for updation (put/remove) & it does not block it for retrieval (get) hence some other
thread can read the same segment, but it will be able to read the data before locking
 It’s important to know get operations does not lock any segment.

HashMap - can be synchronized by using Collections’s class synchronizedMap method in java.
Map synchronizedMap = Collections.synchronizedMap(hashMap);
Now, no 2 threads can access same instance of map concurrently.
Hence synchronized HashMap’s performance is slower as compared to ConcurrentHashMap in java.

Now let’s form few questions to clear your doubts (based on above diagram) >

Question 1 : What will happen map.put(25,12) is called and some other thread concurrently calls map.get(25)?
Answer : When map.put(25,12) is called whole map is locked, When one thread performs any updations (put/remove) on
HashMap it locks whole HashMap and does not allow any other thread to perform updation (put/remove) or retrieval (get)
operations until lock is not released on HashMap.
Hence map.get(25) operation will have to wait for map.put(25,12) operation to release lock on HashMap.

Let’s summarize above section >


What operations lock synchronized HashMap & what operations are allowed when synchronized HashMap is locked >
 When one thread performs any updations (put/remove) on HashMap it locks whole HashMap and does not allow
any other thread to perform updation (put/remove) or retrieval (get) operations until lock is not released on HashMap.
 It’s important to know get operations does not lock HashMap.

What is concurrency level? What is default concurrency level of java.util.concurrent.ConcurrentHashMap in java?


Concurrency level tells how many threads can access ConcurrentHashMap concurrently, default concurrency level of
ConcurrentHashMap is 16 in java.
new ConcurrentHashMap();
Creates a new ConcurrentHashMap with concurrency level of 16.
So, far we have learned what are differences between java.util.HashMap and java.util.ConcurrentHashMap in java. Now
we will learn similarities between java.util.HashMap and java.util.ConcurrentHashMap in Collection framework in java.

Similarity between java.util.HashMap and java.util.concurrent.ConcurrentHashMap in java>


Property java.util.HashMap and
java.util.concurrent.ConcurrentHashMap

Insertion order HashMap and ConcurrentHashMap both does not maintain insertion order.

Implements java.util.Map HashMap and ConcurrentHashMap both are implementation of the java.util.Map interface.

Deadlock in multithreading - program to form DeadLock, solving DeadLock, measures to avoid Deadlock in java.

This is very important question from interview perspective. But, what makes this question important is it checks
interviewees capability of creating and detecting deadlock. If you can write a code to form deadlock, than I am sure you
must be well capable in solving that deadlock as well. If not, later on this post we will learn how to solve deadlock as well.
First question comes to mind is, what is deadlock in multi threading program?
Deadlock is a situation where two threads are waiting for each other to release lock holded by them on resources.

Deadlock creation - how deadlock could be formed in multithreading:

Thread-1 acquires lock on String.class and then calls sleep() method which gives Thread-2 the chance to execute
immediately after Thread-1 has acquired lock on String.class and Thread-2 acquires lock on Object.class then calls sleep()
method and now it waits for Thread-1 to release lock on String.class.
Conclusion:
Now, Thread-1 is waiting for Thread-2 to release lock on Object.class and Thread-2 is waiting for Thread-1 to release
lock on String.class and deadlock is formed.
Code called by Thread-1

public void run() {


synchronized (String.class) {
Thread.sleep(100);
synchronized (Object.class) {
}
}
}

Code called by Thread-2

public void run() {


synchronized (Object.class) {
Thread.sleep(100);
synchronized (String.class) {
}
}
}

Full Program to create Deadlock in multithreading environment >


class A implements Runnable{
public void run() {

synchronized (String.class) {

/*
* Adding this optional delay so that Thread-2 could enough time
* to lock Object class and form deadlock.
* If you remove this sleep, because of threads unpredictable
* behavior it might that Thread-1
* gets completed even before Thread-2 is started and we will
* never form deadLock.
*/
try {
Thread.sleep(100);
} catch (InterruptedException e) {e.printStackTrace();}

System.out.println(Thread.currentThread().getName() + "has acquired lock "


+ "on String class and waiting to acquire lock on Object class...");
synchronized (Object.class) {
System.out.println(Thread.currentThread().getName() +
" has acquired lock on Object class");
}
}

System.out.println(Thread.currentThread().getName()+" has ENDED");


}
}
class B extends Thread{
public void run() {

synchronized (Object.class) {
System.out.println(Thread.currentThread().getName() + " has acquired "
+ "lock on Object class and waiting to acquire lock on String class...");

/*
* Adding this optional delay so that Thread-1 could enough
* time to lock String class and form deadlock.
* If you remove this sleep, because of threads unpredictable
* behavior it might that Thread-2
* gets completed even before Thread-1 is started and we
* will never form deadLock.
*/
try {
Thread.sleep(100);
} catch (InterruptedException e) {e.printStackTrace();}

synchronized (String.class) {
System.out.println(Thread.currentThread().getName() +
" has acquired lock on String class");
}
}

System.out.println(Thread.currentThread().getName()+ " has ENDED");


}
}
public class DeadlockCreation {
public static void main(String[] args) {
Thread thread1 = new Thread(new A(), "Thread-1");
Thread thread2 = new Thread(new B(), "Thread-2");
thread1.start();
thread2.start();
}
}
/*OUTPUT

Thread-2 has acquired lock on Object class and waiting to acquire lock on String class...
Thread-1 has acquired lock on String class and waiting to acquire lock on Object class...
*/
What happened in above program was Thread-1 was waiting for Thread-2 to release lock on Object.class and
Thread-2 was waiting for Thread-1 to release lock on String.class and deadlock was formed. One more crucial thing to
note down in output was " has ENDED" was never printed in output, because of deadlock Thread-1 & Thread-2 never ended.
Solving deadlock - Here comes the important part, how above formed deadlock could be solved :

Thread-1 acquires lock on String.class and then calls sleep() method which gives Thread-2 the chance to execute
immediately after Thread-1 has acquired lock on String.class and Thread-2 tries to acquire lock on String.class but lock is
holded by Thread-1. Meanwhile, Thread-1 completes successfully. As Thread-1 has completed successfully it releases lock
on String.class, Thread-2 can now acquire lock on String.class and complete successfully without any deadlock formation.
Conclusion: No deadlock is formed.
Code called by Thread-1

public void run() {


synchronized (String.class) {
Thread.sleep(100);
synchronized (Object.class) {
}
}
}

Code called by Thread-2

public void run() {


synchronized (String.class) {
Thread.sleep(100);
synchronized (Object.class) {
}
}
}

Full Program to solve Deadlock created in above program>


class A implements Runnable{
public void run() {

synchronized (String.class) {
//using Thread.sleep(100); // is optional.
System.out.println(Thread.currentThread().getName() + " has acquired lock "
+ "on String class and waiting to acquire lock on Object class...");
synchronized (Object.class) {
System.out.println(Thread.currentThread().getName()+" has acquired "
+ "lock on Object class");
}
}

System.out.println(Thread.currentThread().getName()+" has ENDED");


}
}
class B extends Thread{
public void run() {

synchronized (String.class) {
System.out.println(Thread.currentThread().getName()+" has acquired lock on "
+ "Object class and waiting to acquire lock on String class...");

synchronized (Object.class) {
System.out.println(Thread.currentThread().getName()+" has acquired "
+ "lock on String class");
}
}

System.out.println(Thread.currentThread().getName()+" has ENDED");


}
}
public class DeadlockSolution {
public static void main(String[] args) {
Thread thread1=new Thread(new A(),"Thread-1");
Thread thread2=new Thread(new B(),"Thread-2");
thread1.start();
thread2.start();
}
}
/*OUTPUT

Thread-1 has acquired lock on String class and waiting to acquire lock on Object class...
Thread-1 has acquired lock on Object class
Thread-1 has ENDED
Thread-2 has acquired lock on Object class and waiting to acquire lock on String class...
Thread-2 has acquired lock on String class
Thread-2 has ENDED
*/

What happened in above program was Thread-1 acquired lock on String.class and then called sleep() method which
gave Thread-2 the chance to execute immediately after Thread-1 acquired lock on String.class and then Thread-2 tried to
acquire lock on String.class but lock was holded by Thread-1. Meanwhile, Thread-1 completed successfully. As Thread-1
completed successfully it released lock on String.class, Thread-2 then acquired lock on String.class and completed
successfully. Hence, neither of the thread waited for each other to release locks and ended without any deadlock formation.
One more crucial thing to note down in output was " has ENDED" was printed in output, because Thread-1 & Thread-2
completed successfully.

Few important measures to avoid Deadlock >

1. Lock specific member variables of class rather than locking whole class: We must try to lock specific member
variables of class rather than locking whole class.
Example : Let’s say we have a class
class CustomClass{
Integer i;
String str;
}
Now rather than locking object of whole CustomClass try to lock specific fields which we want to synchronize.

Avoid such kind of locking :


CustomClass customClassObj=new CustomClass();
synchronized (customClassObj) {
}

Try to use such kind of locking (locking specific member variable of class) :
synchronized (customClassObj.str) {
}

Benefit of using such kind of locks is that any other thread can easily operate on unlocked member variable of class and
reduce risk of forming deadlock.

2. Use join() method: If possible try to use join() method, although it may refrain us from taking full advantage of
multithreading environment because threads will start and end sequentially, but it can be handy in avoiding deadlocks.
Now , I am going to provide you with source code to give you a better picture of how join() method can be handy in
avoiding deadlock in above used program.

class A implements Runnable{


public void run() {

synchronized (String.class) {

/*
* Adding this optional delay so that Thread-2 could enough time to lock Object class and form deadlock.
* If you remove this sleep, because of threads unpredictable behavior it might that Thread-1
* gets completed even before Thread-2 is started and we will never form deadLock.
*/
try {
Thread.sleep(100);
} catch (InterruptedException e) {e.printStackTrace();}

System.out.println(Thread.currentThread().getName()+" has acquired lock on String class and waiting to


acquire lock on Object class...");
synchronized (Object.class) {
System.out.println(Thread.currentThread().getName()+" has acquired lock on Object class");
}
}

System.out.println(Thread.currentThread().getName()+" has ENDED");


}
}
class B extends Thread{
public void run() {

synchronized (Object.class) {
System.out.println(Thread.currentThread().getName()+" has acquired lock on Object class and waiting to
acquire lock on String class...");

/*
* Adding this optional delay so that Thread-1 could enough time to lock String class and form deadlock.
* If you remove this sleep, because of threads unpredictable behavior it might that Thread-2
* gets completed even before Thread-1 is started and we will never form deadLock.
*/
try {
Thread.sleep(100);
} catch (InterruptedException e) {e.printStackTrace();}

synchronized (String.class) {
System.out.println(Thread.currentThread().getName()+" has acquired lock on String class");
}
}

System.out.println(Thread.currentThread().getName()+" has ENDED");


}
}
public class DeadlockAvoidingUsingJoin {
public static void main(String[] args) throws InterruptedException {
Thread thread1=new Thread(new A(),"Thread-1");
Thread thread2=new Thread(new B(),"Thread-2");
thread1.start();
thread1.join();
thread2.start();
}
}
/*OUTPUT

Thread-1 has acquired lock on String class and waiting to acquire lock on Object class...
Thread-1 has acquired lock on Object class
Thread-1 has ENDED
Thread-2 has acquired lock on Object class and waiting to acquire lock on String class...
Thread-2 has acquired lock on String class
Thread-2 has ENDED
*/
What happened in the above program was, because of join() method Thread-1 and Thread-2 started and ended sequentially.
Thread-1 was able to finish even before Thread-2 was started and no deadlock was formed.

3. If possible try avoid using nested synchronization blocks.


Just another illustration to create deadlock using inner classes (though it’s not going to be much different from deadlock
logic creation used in above programs, but it will give you just way of creating deadlock using inner classes) >

public class DeadlockCreationUsingInnerClasses {


public static void main(String[] args) {
Thread thread1=new Thread("Thread-1"){ //inner class
public void run() {

synchronized (String.class) {

/*
* Adding this optional delay so that Thread-2 could enough time to lock Object class and form
deadlock.
* If you remove this sleep, because of threads unpredictable behavior it might that Thread-1
* gets completed even before Thread-2 is started and we will never form deadLock.
*/
try {
Thread.sleep(100);
} catch (InterruptedException e) {e.printStackTrace();}

System.out.println(Thread.currentThread().getName()+" has acquired lock on String class and waiting


to acquire lock on Object class...");
synchronized (Object.class) {
System.out.println(Thread.currentThread().getName()+" has acquired lock on Object class");
}
}

System.out.println(Thread.currentThread().getName()+" has ENDED");


}
};
Thread thread2=new Thread("Thread-2"){ //inner class
public void run() {

synchronized (Object.class) {
System.out.println(Thread.currentThread().getName()+" has acquired lock on Object class and waiting
to acquire lock on String class...");

/*
* Adding this optional delay so that Thread-1 could enough time to lock String class and form
deadlock.
* If you remove this sleep, because of threads unpredictable behavior it might that Thread-2
* gets completed even before Thread-1 is started and we will never form deadLock.
*/
try {
Thread.sleep(100);
} catch (InterruptedException e) {e.printStackTrace();}

synchronized (String.class) {
System.out.println(Thread.currentThread().getName()+" has acquired lock on String class");
}
}

System.out.println(Thread.currentThread().getName()+" has ENDED");


}
};
thread1.start();
thread2.start();
}
}
/*OUTPUT

Thread-2 has acquired lock on Object class and waiting to acquire lock on String class...
Thread-1 has acquired lock on String class and waiting to acquire lock on Object class...
*/

Detecting Deadlocks >

We can use following tools to generate thread dumps and find out root cause of deadlock by analyzing thread dumps.

VisualVM is most popular way to generate Thread Dump and is most widely used by developers. It’s important to understand usage of
VisualVM for in depth knowledge of VisualVM. I’ll recommend every developer must understand this topic to become master in multi
threading.
It helps us in analyzing threads performance, thread states, CPU consumed by threads, garbage collection and much more. For detailed
information see Generating and analyzing Thread Dumps using VisualVM - step by step detail to setup VisualVM with screenshots

jstack is very easy way to generate Thread dump and is widely used by developers. I’ll recommend every developer must understand this
topic to become master in multi threading. For creating Thread dumps we need not to download any jar or any extra software. For
detailed information see Generating and analyzing Thread Dumps using JSATCK - step by step detail to setup JSTACK with
screenshots.

Thread states/ Thread life cycle in java

Thread states/Thread life cycle is very basic question, before going deep into concepts we must understand Thread
life cycle. This post contains in depth explanation of thread methods explaining which method puts thread from
which state to which state.

Thread have following states >


 New
 Runnable
 Running
 Waiting/blocked/sleeping
 Terminated (Dead)

Thread states in diagram >

Thread states in detail >

New : When instance of thread is created using new operator it is in new state , but the start() method has not been
invoked on the thread yet, thread is not eligible to run yet.
>Thread object is considered alive but thread is not alive yet.

Runnable : When start() method is called on thread it enters runnable state.


>As soon as Thread enters runnable state it is eligible to run, but not running. (Thread scheduler has not scheduled
the Thread execution yet, Thread has not entered in run() method yet)
>A thread first enters the runnable state when the start() method is invoked, but a thread can also return to the
runnable state after either running or coming back from a
blocked, waiting, or sleeping state.
>Thread is considered alive in runnable state.
>Thread is in Runnable pool.

Running : Thread scheduler selects thread to go from runnable to running state. In running state Thread starts executing by
entering run() method.
>Thread scheduler selects thread from the runnable pool on basis of priority, if priority of two threads is same,
threads are scheduled in unpredictable manner. Thread scheduler behaviour is completely unpredictable.
>When threads are in running state, yield() method can make thread to go in Runnable state.

Waiting/blocked/sleeping : In this state a thread is not eligible to run.


>Thread is still alive, but currently it’s not eligible to run. In other words.

> How can Thread go from running to waiting state ?


By calling wait() method thread go from running to waiting state. In waiting state it will wait for other threads to release
object monitor/lock.
> How can Thread return from waiting to runnable state ?
Once notify() or notifyAll() method is called object monitor/lock becomes available and thread can again return to
runnable state.
> How can Thread go from running to sleeping state ?
By calling sleep() method thread go from running to sleeping state. In sleeping state it will wait for sleep time to get over.
> How can Thread return from sleeping to runnable state ?
Once specified sleep time is up thread can again return to runnable state.

Suspend() method can be used to put thread in waiting state and resume() method is the only way which could put thread in
runnable state.

Thread also may go from running to waiting state if it is waiting for some I/O operation to take place. Once input is available
thread may return to running state.

Terminated (Dead) : A thread is considered dead when its run() method completes.
>Once thread is dead it cannot be started again doing so will throw runtimeException i.e.
IllegalThreadStateException.

destroy() method puts thread directly into dead state.

Daemon threads - 12 salient features of Daemon Thread in java

Daemon threads >


Daemon threads are low priority threads which runs intermittently in background for doing garbage collection.

salient features of daemon() threads >

1 Thread scheduler schedules these threads only when CPU is idle.


2. Daemon threads are service oriented threads, they serves all other threads.
3. These threads are created before user threads are created and die after all other user threads dies.
4. Priority of daemon threads is always 1 (i.e. MIN_PRIORITY).
5. User created threads are non daemon threads.
6. JVM can exit when only daemon threads exist in system.
7. Daemon threads are low priority threads which runs intermittently in background for doing garbage collection.
8. we can use isDaemon() method to check whether thread is daemon thread or not.
9. we can use setDaemon(boolean on) method to make any user method a daemon thread. Generally, We must not make
user threads as daemon.
10. If setDaemon(boolean on) is called on thread after calling start() method than IllegalThreadStateException is thrown.
11 You may like to see how daemon threads work, for that you can use VisualVM or jStack. I have provided Thread dumps
over there which shows daemon threads which were intermittently running in background.
Some of the daemon threads which intermittently run in background are >
"RMI TCP Connection(3)-10.175.2.71" daemon
"RMI TCP Connection(idle)" daemon
"RMI Scheduler(0)" daemon
"C2 CompilerThread1" daemon
"GC task thread#0 (ParallelGC)"
Now, Lets create program >

Program to create daemon thread by using setDaemon() method and also use isDaemon() method to check whether thread is
daemon or not.

public class DaemonTest {


public static void main(String[] args) throws InterruptedException {
final Thread thread1=new Thread("Thread-1"){
public void run() {
System.out.println(Thread.currentThread().getName()+" has started");
System.out.println(Thread.currentThread().getName()+" has ended");
}

};
thread1.setDaemon(true); //setting thread to daemon.
System.out.println("is thread1 daemon thread : "
+thread1.isDaemon()); //checking thread isDeamon ?
thread1.start(); //start daemon thread

}
}
/*
is thread1 daemon thread : true
Thread-1 has started
Thread-1 has ended
*/

Program to show > if setDaemon(boolean on) is called on thread after calling start() method than
IllegalThreadStateException is thrown.

public class DaemonTestException {


public static void main(String[] args) throws InterruptedException {

final Thread thread1=new Thread("Thread-1"){


public void run() {
System.out.println(Thread.currentThread().getName()+" has started");
System.out.println(Thread.currentThread().getName()+" has ended");
}

};
thread1.start(); //start daemon thread
thread1.setDaemon(true); //setting thread to daemon after start(), will throw IllegalThreadStateException.

}
}
/*
Thread-1 has started
Thread-1 has ended
Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.Thread.setDaemon(Unknown Source)
at DaemonTestException.main(DaemonTestException.java:13)
*/

Difference between wait() and sleep() method in java in threads

Following are main difference between wait() and sleep() method -

 Should be called from synchronized block : wait() method is always called from synchronized block i.e.
wait() method needs to lock object monitor before object on which it is called. But sleep() method can be called from
outside synchronized block i.e. sleep() method doesn’t need any object monitor.
 IllegalMonitorStateException : if wait() method is called without acquiring object lock than
IllegalMonitorStateException is thrown at runtime, but sleep() method never throws such exception.

 Belongs to which class : wait() method belongs to java.lang.Object class but sleep() method belongs to
java.lang.Thread class.
 Called on object or thread : wait() method is called on objects but sleep() method is called on Threads not
objects.

 Thread state : when wait() method is called on object, thread that holded object’s monitor goes from
running to waiting state and can return to runnable state only when notify() or notifyAll() method is called on that
object. And later thread scheduler schedules that thread to go from from runnable to running state.
when sleep() is called on thread it goes from running to waiting state and can return to runnable state when sleep time
is up.

 When called from synchronized block : when wait() method is called thread leaves the object lock. But sleep()
method when called from synchronized block or method thread doesn’t leaves object lock.

Sleep() method in threads in java - 10 key features with programs

 Definition : sleep() methods causes current thread to sleep for specified number of milliseconds (i.e. time
passed in sleep method as parameter). Ex- Thread.sleep(10) causes currently executing thread to sleep for 10 millisec.

 Thread state : when sleep() is called on thread it goes from running to waiting state and can return to runnable
state when sleep time is up.

 Exception : sleep() method throws compile time exception i.e. InterruptedException.

 Waiting time : sleep() method have got few options.


1. sleep(long millis) - Causes the currently executing thread to sleep for the specified number of
milliseconds

public static native void sleep(long millis) throws InterruptedException;

2. sleep(long millis, int nanos) - Causes the currently executing thread to sleep for the specified number of
milliseconds plus the specified number of nanoseconds.

public static native void sleep(long millis,int nanos) throws InterruptedException;

 static method : sleep() is a static method, causes the currently executing thread to sleep for the specified number
of milliseconds.

 Native method : implementation of sleep() method is provided by JVM.


Let’s see definition of yield() method as given in java.lang.Thread -
public static native void sleep(long millis) throws InterruptedException;

 Belongs to which class : sleep() method belongs to java.lang.Thread class.

 synchronized block : thread need not to to acquire object lock before calling sleep() method i.e. sleep() method
can be called from outside synchronized block.

Using sleep() method in main thread >


public class SleepMain {
public static void main(String...args) throws InterruptedException{
System.out.println(Thread.currentThread().getName() + " has started");
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName() + " has ended");
}
}
/*OUTPUT
main has started
main has ended
*/
In the above program, main thread starts than it call sleep(2000) method and it enters waiting state for 2000 millisec (2
seconds). Once 2 seconds are over main thread comes into running state and finish its execution.

Using sleep() method in thread invoked by main thread >


class MyRunnable implements Runnable {
public void run() {
System.out.println(Thread.currentThread().getName() + " has started");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " has ended");
}
}
public class SleepRunnable {
public static void main(String... args) {
System.out.println(Thread.currentThread().getName() + " has started");
Thread thread1 = new Thread(new MyRunnable(), "Thread-1");
thread1.start();
System.out.println(Thread.currentThread().getName() + " has ended");
}
}
/*OUTPUT
main has started
main has ended
Thread-1 has started
Thread-1 has ended

*/
In the above program, main thread starts invokes Thread-1 and Thread-1 calls sleep method and it enters waiting state for
2000 millisec, meanwhile main thread gets chance to execute and finish. Once 2 seconds are over Thread-1 comes into
running state and finish its execution.

Above we read that sleep() is a static method, let’s understand it by program>


 static method : sleep() is a static method, causes the currently executing thread to sleep for the specified number
of milliseconds.

In the below program first main thread started, than it invoked Thread-1, then Thread-1 called sleep(100) method to ensure
that main thread don’t complete before Thread-1, than execution control went to main thread and it called
thread1.sleep(10000) but rather than putting Thread-1 on sleep it made main thread to sleep. And Thread-1 ended
before main thread.
class MyRunnable implements Runnable {
public void run() {
System.out.println(Thread.currentThread().getName() + " has started");
try {
Thread.sleep(100); //ensure that main thread don’t complete before Thread-1
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " has ended");
}
}
public class SleepStatic {
public static void main(String... args) throws InterruptedException {
System.out.println(Thread.currentThread().getName() + " has started");
Thread thread1 = new Thread(new MyRunnable(), "Thread-1");
thread1.start();
thread1.sleep(10000); //we will face warning - The static method
//sleep(long) from the type Thread should be accessed in a static way
System.out.println(Thread.currentThread().getName() + " has ended");
}
}
/*OUTPUT
main has started
Thread-1 has started
Thread-1 has ended
main has ended
*/

Wait() and notify() methods in java - Definition, 8 key features, solving consumer producer problem with & without
these methods and consequences of not using wait() and notify() methods.
notify() - Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of
them is chosen to be awakened. The choice is random and occurs at the discretion of the implementation. A thread waits on
an object's monitor by calling one of the wait methods.

The awakened threads will not be able to proceed until the current thread relinquishes the lock on this object.

notifyAll() - Wakes up all threads that are waiting on this object's monitor. A thread waits on an object's monitor by calling
one of the wait methods.
The awakened threads will not be able to proceed until the current thread relinquishes the lock on this object.

wait() - Causes the current thread to wait until another thread invokes the notify() or notifyAll() method for this object.
The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another
thread notifies threads waiting on this object's monitor to wake up either through a call to the notify()/ notifyAll() method.
The thread then waits until it can re-obtain ownership of the monitor and resumes execution.

 Thread state :
>By calling wait() method thread go from running to waiting state. In waiting state it will wait for other threads
to release object monitor/lock.
> Once notify() or notifyAll() method is called object monitor/lock becomes available and thread can again return to
runnable state.
 synchronized block : thread needs to to acquire object lock before calling wait() and notify() methods i.e. these
methods can be called only from synchronized block or synchronized method.

 Exception : As mentioned above before calling these methods thread must own object’s monitor means wait() and
notify() methods must be called from synchronized blocks or synchronized method otherwise IllegalMonitorStateException
is thrown at runtime.

 Waiting time : wait() and notify() method have got few options.
1. wait() - It internally calls wait(0).

2. wait(long timeout) - Causes the current thread to wait until either another thread invokes the notify() or
notifyAll() methods for this object, or a specified timeout time has elapsed.

public final native void wait(long timeout) throws InterruptedException;

3. wait(long timeout, int nanos) - Causes the current thread to wait until either another thread invokes the
notify() or notifyAll() methods for this object, or a specified timeout time plus the specified number of
nanoseconds has elapsed.

public static native void wait(long timeout,int nanos) throws InterruptedException;

notify() and notifyAll()


public final native void notify();
public final native void notifyAll();

 Instance methods : wait() and notify() are instance methods and are always called on objects.
 Native methods : implementation of wait() and notify() methods are provided by JVM.
Let’s see definition of wait() and notify() method as given in java.lang.Object -
public final void wait() throws InterruptedException

public final native void notify();


public final native void notifyAll();

 Belongs to which class : wait() and notify() methods belongs to java.lang.Object class.

Below i tried to give a very simple example to show usgae of wait() and notify() method to give you better understanding of
these methods.

Solve Consumer Producer problem by using wait() and notify() methods, where consumer can consume only when
production is over.
Producer will allow consumer to consume only when 10 products have been produced (i.e. when production is over).

Thought, we can solve this producer consumer problem without using wait() and notify() method as well, below i have
given consequences of not using using wait() and notify().

In program consumer thread will start() and wait by calling wait() method till producer is producing. Once
production is over, producer thread will call notify() method, which will notify consumer thread and consumer will
start consuming.
import java.util.ArrayList;
/* Producer is producing, Producer will allow consumer to
* consume only when 10 products have been produced (i.e. when production is over).
*/
class Producer implements Runnable{
ArrayList<Integer> sharedQueue;

Producer(){
sharedQueue=new ArrayList<Integer>();
}

@Override
public void run(){

synchronized (this) {
for(int i=1;i<=10;i++){ //Producer will produce 10 products
sharedQueue.add(i);
System.out.println("Producer is still Producing, Produced : "+i);

try{
Thread.sleep(1000);
}catch(InterruptedException e){e.printStackTrace();}

}
System.out.println("Production is over, consumer can consume.");
this.notify(); //Production is over, notify consumer thread so that consumer can consume.
}
}

}
class Consumer extends Thread{
Producer prod;

Consumer(Producer obj){
prod=obj;
}

public void run(){


/*
* consumer will wait till producer is producing.
*/
synchronized (this.prod) {

System.out.println("Consumer waiting for production to get over.");


try{
this.prod.wait();
}catch(InterruptedException e){e.printStackTrace();}

/*production is over, consumer will start consuming.*/


int productSize=this.prod.sharedQueue.size();
for(int i=0;i<productSize;i++)
System.out.println("Consumed : "+ this.prod.sharedQueue.remove(0) +" ");

}
public class ProducerConsumerWithWaitNotify {
public static void main(String args[]) throws InterruptedException{

Producer prod=new Producer();


Consumer cons=new Consumer(prod);

Thread prodThread=new Thread(prod,"prodThread");


Thread consThread=new Thread(cons,"consThread");

consThread.start(); //start consumer thread.


Thread.sleep(100); //This minor delay will ensure that consumer thread starts before producer thread.
prodThread.start(); //start producer thread.

}
}
/*OUTPUT
Consumer waiting for production to get over.
Producer is still Producing, Produced : 1
Producer is still Producing, Produced : 2
Producer is still Producing, Produced : 3
Producer is still Producing, Produced : 4
Producer is still Producing, Produced : 5
Producer is still Producing, Produced : 6
Producer is still Producing, Produced : 7
Producer is still Producing, Produced : 8
Producer is still Producing, Produced : 9
Producer is still Producing, Produced : 10
Production is over, consumer can consume.
Consumed : 1
Consumed : 2
Consumed : 3
Consumed : 4
Consumed : 5
Consumed : 6
Consumed : 7
Consumed : 8
Consumed : 9
Consumed : 10
*/

But what could be consequences of not using using wait() and notify() to solve above producer consumer problem?
It will cost of us performance. Consumer thread will unnecessarily repeatedly check whether producer has completed
it’s production or not, but when wait() and notify() were used, consumer thread started, called wait() and waited for
producer thread to notify.
Let’s identify Problem statement in not using wait() and notify()>
while(this.prod.productionInProcess)

Using while loop is the actual problem statement in not using wait() and notify(), loops generally costs us performance and
we must try to avoid loops.
Let’ say producer was to producer 100 products and for every production it takes 10 seconds & consumer is checking after
every 20seconds whether production is over or not. In that case consumer will check after every every 2 products produced
whether production is over or not, unnecessary 50 calls will be made, which will of course slow down our whole process.

But now, let's solve above problem without using wait() and notify() - approach which won’t be performance friendly (but
provides developers a choice to solve producer consumer problem in different manner).

How to solve Consumer Producer problem without using wait() and notify() methods, where consumer can consume only
when production is over.

Producer will allow consumer to consume only when 10 products have been produced (i.e. when production is over).

We will approach by keeping one boolean variable productionInProcess and initially setting it to true, and later when
production will be over we will set it to false.

In program producer thread will start() and it will start producing and called sleep(1000) in between, which will give
consumer thread chance to execute. consumer checks whether productionInProcess is true or not, if it's true,
consumer will sleep(4000) and wake up after specified time and again check whether productionInProcess is true or
false. process will repeat till productionInProcess is true. Meanwhile, producer thread will complete production and
ultimately make productionInProcess to false. Once productionInProcess is false, consumer will consume.

import java.util.ArrayList;
/* Producer is producing, Producer will allow consumer to
* consume only when 10 products have been produced (i.e. when production is over).
*/
class Producer implements Runnable{

boolean productionInProcess;
ArrayList<Integer> list;

Producer(){
productionInProcess=true; //initially Producer will be producing, so make this productionInProcess true.
list=new ArrayList<Integer>();
}

@Override
public void run(){

for(int i=1;i<=10;i++){ //Producer will produce 10 products


list.add(i);
System.out.println("Producer is still Producing, Produced : "+i);

try{
Thread.sleep(1000);
}catch(InterruptedException e){e.printStackTrace();}

}
productionInProcess=false; // Once production is over, make this productionInProcess false.
//Production is over, consumer can consume.

}
class Consumer extends Thread{
Producer prod;
Consumer(Producer obj){
prod=obj;
}

public void run(){


/*
* consumer checks whether productionInProcess is true or not, if it's true,
* consumer will sleep and wake up after certain time and again check whether productionInProcess is true or false.
* process will repeat till productionInProcess is true.
* Once productionInProcess is false we'll exit below while loop.
*/
while(this.prod.productionInProcess){ //costing us performance
System.out.println("Consumer waiting for production to get over.");
try{
Thread.sleep(4000);
}catch(InterruptedException e){e.printStackTrace();}

/*productionInProcess is false means production is over, consumer will start consuming. */


System.out.println("Production is over, consumer can consume.");
int productSize=this.prod.list.size();
for(int i=0;i<productSize;i++)
System.out.println("Consumed : "+ this.prod.list.remove(0) +" ");

}
public class ProducerConsumerWithoutWaitNotify {
public static void main(String args[]){

Producer prod=new Producer();


Consumer cons=new Consumer(prod);

Thread prodThread=new Thread(prod,"prodThread");


Thread consThread=new Thread(cons,"consThread");

prodThread.start(); //start producer thread.


consThread.start(); //start consumer thread.

}
}
/*OUTPUT
Consumer waiting for production to get over.
Producer is still Producing, Produced : 1
Producer is still Producing, Produced : 2
Producer is still Producing, Produced : 3
Producer is still Producing, Produced : 4
Producer is still Producing, Produced : 5
Producer is still Producing, Produced : 6
Producer is still Producing, Produced : 7
Producer is still Producing, Produced : 8
Producer is still Producing, Produced : 9
Producer is still Producing, Produced : 10
Production is over, consumer can consume.
Consumed : 1
Consumed : 2
Consumed : 3
Consumed : 4
Consumed : 5
Consumed : 6
Consumed : 7
Consumed : 8
Consumed : 9
Consumed : 10
*/

Differences and similarities between yield() and sleep() in java in threads


Differences yield() and sleep() :

 Definition : yield() method when called on thread gives a hint to the thread scheduler that the current
thread is willing to yield its current use of a processor. The thread scheduler is free to ignore this hint. sleep()
methods causes current thread to sleep for specified number of milliseconds (i.e. time passed in sleep method as
parameter). Ex- Thread.sleep(10) causes currently executing thread to sleep for 10 millisec.

 Thread state : when sleep() is called on thread it goes from running to waiting state and can return to runnable
state when sleep time is up. when yield() method is called on thread it goes from running to runnable state, not in
waiting state. Thread is eligible to run but not running and could be picked by scheduler at anytime.

 Exception : yield() method doesn’t throws any exception. But sleep() method throws compile time exception
i.e. InterruptedException.

 Waiting time : yield() method stops thread for unpredictable time, that depends on thread scheduler. But
sleep() method have got few options.
1. sleep(long millis) - Causes the currently executing thread to sleep for the specified number of
milliseconds
2. sleep(long millis, int nanos) - Causes the currently executing thread to sleep for the specified number of
milliseconds plus the specified number of nanoseconds.

similarity between yield() and sleep():

> yield() and sleep() method belongs to java.lang.Thread class.

> yield() and sleep() method can be called from outside synchronized block.

> yield() and sleep() method are called on Threads not objects.

Mention some guidelines to write thread safe code, most important point we must take care of in multithreading
programs?
In multithreading environment it’s important very important to write thread safe code, thread unsafe code can cause a major
threat to your application. I have posted many articles regarding thread safety. So overall this will be revision of what we
have learned so far i.e. writing thread safe healthy code and avoiding any kind of deadlocks.\

What will happen if we don’t override run method?


This question will test your basic knowledge how start and run methods work internally in Thread Api.

When we call start() method on thread, it internally calls run() method with newly created thread. So, if we don’t
override run() method newly created thread won’t be called and nothing will happen.

What will happen if we override start method?


This question will again test your basic core java knowledge how overriding works at runtime, what will be called at runtime
and how start and run methods work internally in Thread Api.

When we call start() method on thread, it internally calls run() method with newly created thread. So, if we override
start() method, run() method will not be called until we write code for calling run() method.

Can we acquire lock on class? What are ways in which you can acquire lock on class?
Yes, we can acquire lock on class’s class object in 2 ways to acquire lock on class.
Thread can acquire lock on class’s class object by-
1. Entering synchronized block
synchronized (MyClass.class) {
//thread has acquired lock on MyClass’s class object.
}
Or,
2. by entering static synchronized methods.
public static synchronized void method1() {
//thread has acquired lock on MyRunnable’s class object.
}

How can you implement your own Thread Pool in java?


ThreadPool is a pool of threads which reuses a fixed number of threads to execute tasks.
At any point, at most nThreads threads will be active processing tasks. If additional tasks are submitted when all
threads are active, they will wait in the queue until a thread is available.
ThreadPool implementation internally uses LinkedBlockingQueue for adding and removing tasks.
In this post i will be using LinkedBlockingQueue provided by java Api, you can refer this post for implementing ThreadPool
using custom LinkedBlockingQueue.

What is busy spin?

When one thread loops continuously waiting for another thread to signal.

Performance point of view - Busy spin is very bad from performance point of view, because one thread keeps on looping
continuously ( and consumes CPU) waiting for another thread to signal.

Solution to busy spin -


We must use sleep() or wait() and notify() method. Using wait() is better option.

Program - Consumer Producer problem with busy spin >


Consumer thread continuously execute (busy spin) in while loop till productionInProcess is true. Once producer thread has
ended it will make boolean variable productionInProcess false and busy spin will be over.
while(productionInProcess){
System.out.println("BUSY SPIN - Consumer waiting for production to get over");
}

What is executor framework?


Executor and ExecutorService are used for following purposes >
 creating thread,
 starting threads,
 managing whole life cycle of Threads.
Executor creates pool of threads and manages life cycle of all threads in it.
In Executor framework, Executor interface and ExecutorService class are most prominently used.
Executor interface defines very important execute() method which executes command.
ExecutorService interface extends Executor interface.
An Executor interface provides following type of methods >
 methods for managing termination and
 methods that can produce a Future for tracking progress of tasks.

What is Semaphore in java 7?


A semaphore controls access to a shared resource by using permits.
 If permits are greater than zero, then semaphore allow access to shared resource.
 If permits are zero or less than zero, then semaphore does not allow access to shared resource.
These permits are sort of counters, which allow access to the shared resource. Thus, to access the resource, a thread must be
granted a permit from the semaphore.

Guidelines to thread safe code, most important point we must take care of in multithreading programs

In multithreading environment it’s very important to write thread safe, thread unsafe code can cause a major threat to your
application. I have posted many articles regarding thread safety. So overall this article will be revision of what we have
learned so far i.e. writing thread safe healthy code and avoiding any kind of deadlocks.
1. If method is exposed in multithreading environment and it’s not synchronized (thread unsafe) than it might lead us
to race condition, we must try to use synchronized block and synchronized methods. Multiple threads may exist on same
object but only one thread of that object can enter synchronized method at a time, though threads on different object can
enter same method at same time.

2. Even static variables are not thread safe, they are used in static methods and if static methods are not synchronized
then thread on same or different object can enter method concurrently. Multiple threads may exist on same or
different objects of class but only one thread can enter static synchronized method at a time, we must consider
making static methods as synchronized.

3. If possible, try to use volatile variables. If a field is declared volatile all threads see a consistent value for the
variable. Volatile variables at times can be used as alternate to synchronized methods as well.

4. Final variables are thread safe because once assigned some reference of object they cannot point to reference of
other object.

s is pointing to String object.


public class MyClass {
final String s=new String("a");
void method(){
s="b"; //compilation error, s cannot point to new reference.
}
}

If final is holding some primitive value it cannot point to other value.

public class MyClass {


final int i=0;
void method(){
i=0; //compilation error, i cannot point to new value.
}
}

5. Usage of local variables : If possible try to use local variables, local variables are thread safe, because every
thread has its own stack, i.e. every thread has its own local variables and its pushes all the local variables on stack.

public class MyClass {


void method(){
int i=0; //Local variable, is thread safe.
}
}

6. We must avoid using deadlock prone deprecated thread methods such as destroy(), stop(), suspend() and
resume().

7. Using thread safe collections : Rather than using ArrayList we must Vector and in place of using HashMap we
must use ConcurrentHashMap or HashTable.

8. We must use VisualVM or jstack to detect problems such as deadlocks and time taken by threads to complete in
multi threading programs.

9. Using ThreadLocal : ThreadLocal is a class which provides thread-local variables. Every thread has its own
ThreadLocal value that makes ThreadLocal value threadsafe as well.

10. Rather than StringBuffer try using immutable classes such as String. Any change to String produces new String.
Difference between notify() and notifyAll() methods, with program

Theoretically you must have heard or you must be aware of differences between notify() and notifyAll().But have you
created program to achieve it? If not let’s do it.

First, I will like give you a brief description of what notify() and notifyAll() methods do.

notify() - Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of
them is chosen to be awakened. The choice is random and occurs at the discretion of the implementation. A thread waits on
an object's monitor by calling one of the wait methods.
The awakened threads will not be able to proceed until the current thread relinquishes the lock on this object.
public final native void notify();

notifyAll() - Wakes up all threads that are waiting on this object's monitor. A thread waits on an object's monitor by calling
one of the wait methods.
The awakened threads will not be able to proceed until the current thread relinquishes the lock on this object.

public final native void notifyAll();

Now it’s time to write down a program to prove the point >

I guess by this time you must be well capable or writing a program to show differences between notify() and notifyAll()
method. But did you saw above mentioned line ”The awakened threads will not be able to proceed until the current
thread relinquishes the lock on this object” . What does it mean?
It means when notify() method is called on object, thread notifies the other thread waiting on this object's monitor. But
thread does not immediately releases the object lock, it waits for synchronization block to complete.

Program (Execute code by commenting or uncommenting either of notify() or notifyAll() method)>


class MyRunnable1 extends Thread{

public void run(){

synchronized (this) {
System.out.println(Thread.currentThread().getName()+" started");

try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println(Thread.currentThread().getName()+" has been notified");


}
}

}
class MyRunnable2 extends Thread{

MyRunnable1 myRunnable1;

MyRunnable2(MyRunnable1 MyRunnable1){
this.myRunnable1=MyRunnable1;
}

public void run(){

synchronized (this.myRunnable1) {
System.out.println(Thread.currentThread().getName()+ " started");

try {
this.myRunnable1.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" has been notified");
}

}
}
class MyRunnable3 extends Thread{

MyRunnable1 myRunnable1;

MyRunnable3(MyRunnable1 MyRunnable1){
this.myRunnable1=MyRunnable1;
}

public void run(){


synchronized (this.myRunnable1) {
System.out.println(Thread.currentThread().getName()+ " started");

this.myRunnable1.notify(); // Wakes up a single thread that is


//waiting on this object's monitor.
//If any threads are waiting on this object,
//one of them is chosen to be awakened.
//The choice is random and occurs at the
//discretion of the implementation.

//this.myRunnable1.notifyAll(); // Will wake up all threads


//waiting on object's monitor.
System.out.println(Thread.currentThread().getName()+
" has notified waiting threads");
}

}
}

public class CallNotify {


public static void main(String[] args) throws InterruptedException {

MyRunnable1 myRunnable1=new MyRunnable1();


MyRunnable2 myRunnable2=new MyRunnable2(myRunnable1);
MyRunnable3 myRunnable3=new MyRunnable3(myRunnable1);
Thread t1=new Thread(myRunnable1,"Thread-1");
Thread t2=new Thread(myRunnable2,"Thread-2");
Thread t3=new Thread(myRunnable3,"Thread-3");

t1.start();
t2.start();
Thread.sleep(100); //Used to ensure that thread1 and thread2 starts before thread-3
//because thread-1 and 2 calls wait(), while thread-3 calls notify or notifyAll()
t3.start();

}
}
/* OUTPUT with notify()
Thread-1 started
Thread-2 started
Thread-3 started
Thread-3 has notified waiting threads
Thread-1 has been notified
*/
/* OUTPUT with notifyAll()
Thread-1 started
Thread-2 started
Thread-3 started
Thread-3 has notified waiting threads
Thread-1 has been notified
Thread-2 has been notified
*/

Let’s take a quick look at output -

When we called notify() -


Only one of the two waiting thread was notified (i.e. Thread-1 and Thread-2 were waiting and only Thread-1 was notified)

When we called notifyall() -


Both of two waiting threads were notified (i.e. Thread-1 and Thread-2 were waiting and both were notified)

What will happen if we don’t override run method of thread in java?

This question will test your basic knowledge how start and run methods work internally in Thread Api.

When we call start() method on thread, it internally calls run() method with newly created thread. So, if we don’t
override run() method newly created thread won’t be called and nothing will happen.

class MyThread extends Thread {


//don't override run() method
}
public class DontOverrideRun {
public static void main(String[] args) {
System.out.println("main has started.");
MyThread thread1=new MyThread();
thread1.start();
System.out.println("main has ended.");
}
}
/*OUTPUT
main has started.
main has ended.
*/
As we saw in output, we didn’t override run() method that’s why on calling start() method nothing happened.

What will happen if we override start method of thread in java?

This question will again test your basic core java knowledge how overriding works at runtime, what will be called at runtime
and how start and run methods work internally in Thread Api.

When we call start() method on thread, it internally calls run() method with newly created thread. So, if we override
start() method, run() method will not be called until we write code for calling run() method.

class MyThread extends Thread {


@Override
public void run() {
System.out.println("in run() method");
}

@Override
public void start(){
System.out.println("In start() method");
}

}
public class OverrideStartMethod {
public static void main(String[] args) {
System.out.println("main has started.");

MyThread thread1=new MyThread();


thread1.start();

System.out.println("main has ended.");


}
}
/*OUTPUT
main has started.
In start() method
main has ended.
*/
If we note output. we have overridden start method and didn’t called run() method from it, so, run() method wasn’t call.

Acquiring lock on class, 2 Ways to acquire lock on class in java


In previous post we learned how to acquire object’s lock. Now, we will learn how to acquire lock on class’s class object. It’s
very important to understand difference between object lock and class lock as well.

Class Level Lock:- Its mainly used to make static level data thread safe…..
Object level Lock:- This can always be done to make instance-level data thread-safe.

Thread can acquire lock on class’s class object by-


1. Entering synchronized block or
2. by entering static synchronized methods.

1) First let’s acquire lock on class’s class object by entering synchronized block.

Let’s say there is one class MyClass. Now we can create synchronization block, and parameter passed with synchronization
tells which class has to be synchronized. In below code, we have synchronized MyClass
synchronized (MyClass.class) {
//thread has acquired lock on MyClass’s class object.
}

As soon as thread entered Synchronization block, thread acquired MyClass’s class object. Thread will leave lock when it
exits synchronized block.

It’s important to know that multiple objects of class may exist but there is always one class’s class object lock available.

Now, let’s create a program >


class MyRunnable1 implements Runnable{
@Override
public void run(){
synchronized (MyClass.class) {
for(int i=0;i<5;i++){
System.out.println(i+" "+Thread.currentThread().getName()+" is
executing");
try {
Thread.sleep(500);
} catch (InterruptedException e) {e.printStackTrace(); }
}
}
}

public class MyClass {


public static void main(String args[]) throws InterruptedException{
MyRunnable1 object1=new MyRunnable1();
MyRunnable1 object2=new MyRunnable1();

Thread thread1=new Thread(object1,"Thread-1");


Thread thread2=new Thread(object2,"Thread-2");
thread1.start();
thread2.start();

}
}
/*OUTPUT
0 Thread-1 is executing
1 Thread-1 is executing
2 Thread-1 is executing
3 Thread-1 is executing
4 Thread-1 is executing
0 Thread-2 is executing
1 Thread-2 is executing
2 Thread-2 is executing
3 Thread-2 is executing
4 Thread-2 is executing
*/
If you note output, Thread-1 entered synchronized block and was holding lock on MyClass’s class object. So, Thread-2
waited for Thread-1 to release lock on MyClass’s class object so that it could enter synchronized block.

2) Now let’s acquire class lock by entering static synchronized method.

Our static synchronized method looks like >


public static synchronized void method1() {
//thread has acquired lock on MyRunnable’s class object.
}

As soon as thread entered Synchronization method, thread acquired lock on class’s class object.
Thread will leave lock when it exits static synchronized method.
It’s important to know that multiple threads may exist on same or different objects of class but only one thread can enter
static synchronized method at a time.

Now, let’s create a program >


class MyRunnable implements Runnable{
@Override
public void run(){
method1();

}
public static synchronized void method1(){
for(int i=0;i<5;i++){
System.out.println(i+" "+Thread.currentThread().getName()+" is
executing");
try {
Thread.sleep(500);
} catch (InterruptedException e) {e.printStackTrace(); }
}
}

}
public class MyClass {
public static void main(String args[]) throws InterruptedException{
MyRunnable object1=new MyRunnable();
MyRunnable object2=new MyRunnable();

Thread thread1=new Thread(object1,"Thread-1");


Thread thread2=new Thread(object2,"Thread-2");
thread1.start();
thread2.start();

}
}
/*OUTPUT
0 Thread-1 is executing
1 Thread-1 is executing
2 Thread-1 is executing
3 Thread-1 is executing
4 Thread-1 is executing
0 Thread-2 is executing
1 Thread-2 is executing
2 Thread-2 is executing
3 Thread-2 is executing
4 Thread-2 is executing
*/
If you note output, Thread-1 entered static synchronized method and was holding lock on MyRunnable’s class object. So,
Thread-2 waited for Thread-1 to release lock on MyRunnable’s class object so that it could enter static synchronized
method.

But, it may also happen that Thread-2 might enter static synchronized method first and in that case output will be -

/*OUTPUT
0 Thread-2 is executing
1 Thread-2 is executing
2 Thread-2 is executing
3 Thread-2 is executing
4 Thread-2 is executing
0 Thread-1 is executing
1 Thread-1 is executing
2 Thread-1 is executing
3 Thread-1 is executing
4 Thread-1 is executing
*/
If you note output, Thread-2 entered static synchronized method and was holding lock on MyRunnable’s class object. So,
Thread-1 waited for Thread-2 to release lock on MyRunnable’s class object so that it could enter static synchronized
method.

Difference between object Lock and class Lock in java

It is very important multithreading topic. We must understand this difference to answer interview, ocjp answers correctly.

Difference between object Lock and class Lock : -

Object lock Class lock

Thread can acquire object lock by- Thread can acquire lock on class’s class object by-
1. Entering synchronized block or 1. Entering synchronized block or
2. by entering synchronized methods. 2. by entering static synchronized methods.

Multiple threads may exist on same object but only one thread of Multiple threads may exist on same or different
that object can enter synchronized method at a time. objects of class but only one thread can enter static
synchronized method at a time.
Threads on different object can enter same method at same time.

Multiple objects of class may exist and every object has it’s Multiple objects of class may exist but there is
own lock. always one class’s class object lock available.

First let’s acquire object lock by entering synchronized block. First let’s acquire lock on class’s class object by
entering synchronized block.
Example- Let’s say there is one class MyClass and we have
created it’s object and reference to that object is myClass. Now Example- Let’s say there is one class MyClass. Now
we can create synchronization block, and parameter passed with we can create synchronization block, and parameter
synchronization tells which object has to be synchronized. In passed with synchronization tells which class has to
below code, we have synchronized object reference by myClass. be synchronized. In below code, we have
MyClass myClass=new Myclass(); synchronized MyClass
synchronized (myClass) { synchronized (MyClass.class) {
} }
As soon thread entered Synchronization block, thread acquired
object lock on object referenced by myClass (by acquiring As soon as thread entered Synchronization block,
object’s monitor.) thread acquired MyClass’s class object. Thread will
Thread will leave lock when it exits synchronized block. leave lock when it exits synchronized block.

public synchronized void method1() { public static synchronized void method1() {}


} As soon as thread entered static Synchronization
method, thread acquired lock on class’s class object.
As soon as thread entered Synchronization method, thread Thread will leave lock when it exits synchronized
acquired object lock. method.
Thread will leave lock when it exits synchronized method.

Implementing ThreadPool using custom LinkedBlockingQueue in java

What is ThreadPool?
ThreadPool is a pool of threads which reuses a fixed number of threads to execute tasks.

At any point, at most nThreads threads will be active processing tasks. If additional tasks are submitted when all
threads are active, they will wait in the queue until a thread is available.
ThreadPool implementation internally uses LinkedBlockingQueue for adding and removing tasks.
In this post i will be using custom LinkedBlockingQueue, you can refer this post for implementing ThreadPool using Java
Api’s LinkedBlockingQueue & also for more detailed information on ThreadPool.

How ThreadPool works?


We will instantiate ThreadPool, in ThreadPool’s constructor nThreads number of threads are created and started.
ThreadPool threadPool=new ThreadPool(2);

Here 2 threads will be created and started in ThreadPool.


Then, threads will enter run() method of ThreadPoolsThread class and will call take() method on taskQueue.
 If tasks are available thread will execute task by entering run() method of task (As tasks executed always
implements Runnable).

public void run() {


...
while (true) {
...
Runnable runnable = taskQueue.take();
runnable.run();
...
}
...
}

 Else waits for tasks to become available.


When tasks are added?
When execute() method of ThreadPool is called, it internally calls put() method on taskQueue to add tasks.
taskQueue.put(task);
Once tasks are available all waiting threads are notified that task is available.

How threads in ThreadPool can be stopped?


shutDown() method can be used to stop threads executing in threadPool, once shutdown of ThreadPool is initiated,
previously submitted tasks are executed, but no new tasks could be accepted.

After thread has executed task


1. Check whether pool shutDown has been initiated or not, if pool shutDown has been initiated and
2. taskQueue does not contain any unExecuted task (i.e. taskQueue's size is 0 )
than interrupt() the thread.

public void run() {


...
while (true) {
...
runnable.run();
//task EXECUTED
...

if(this.threadPool.isPoolShutDownInitiated() &&
this.taskQueue.size()==0)
this.interrupt();

}
...
}

Program to implement ThreadPool in java using custom LinkedBlockingQueue>

package ThreadPoolUsingLinkedBlockingQueueCustom;
import java.util.LinkedList;
import java.util.List;
/**
* Implementing custom BlockingQueue interface .
* This BlockingQueue implementation follows FIFO (first-in-first-out).
* New elements are inserted at the tail of the queue,
* and removal elements is done at the head of the queue.
*
* @author AnkitMittal
* Copyright (c), AnkitMittal .
* All Contents are copyrighted and must not be reproduced in any form.
*/
interface BlockingQueueCustom<E> {
/**
* Inserts the specified element into this queue
* only if space is available else
* waits for space to become available.
*/
void put(E item) throws InterruptedException ;
/**
* Retrieves and removes the head of this queue
* only if elements are available else
* waits for element to become available.
*/
E take() throws InterruptedException;

/**
* Returns size of queue.
*/
int size();
}
/**
* Implementing custom LinkedBlockingQueue class.
* This BlockingQueue implementation follows FIFO (first-in-first-out).
* New elements are inserted at the tail of the queue,
* and removal elements is done at the head of the queue.
*
* @author AnkitMittal
* Copyright (c), AnkitMittal .
* All Contents are copyrighted and must not be reproduced in any form.
*/
class LinkedBlockingQueueCustom<E> implements BlockingQueueCustom<E>{
private List<E> queue;
private int maxSize ; //maximum number of elements queue can hold at a time.
public LinkedBlockingQueueCustom(int maxSize){
this.maxSize = maxSize;
queue = new LinkedList<E>();
}
/**
* Inserts the specified element into this queue
* only if space is available else
* waits for space to become available.
* After inserting element it notifies all waiting threads.
*/
public synchronized void put(E item) throws InterruptedException {

//check space is available or not.


if (queue.size() == maxSize) {
this.wait();
}

//space is available, insert element and notify all waiting threads.


queue.add(item);
this.notifyAll();
}
/**
* Retrieves and removes the head of this queue
* only if elements are available else
* waits for element to become available.
* After removing element it notifies all waiting threads.
*/
public synchronized E take() throws InterruptedException{
//waits element is available or not.
if (queue.size() == 0) {
this.wait();
}
//element is available, remove element and notify all waiting threads.
this.notifyAll();
return queue.remove(0);

}
/**
* Returns size of LinkedBlockingQueueCustom.
*/
public synchronized int size() {
return queue.size();
}
}
/**
* ThreadPool is a class which creates a thread pool that reuses a fixed
* number of threads to execute tasks.
* At any point, at most nThreads threads will be active processing tasks.
* If additional tasks are submitted when all threads are active,
* they will wait in the queue until a thread is available.
*
* Once shutdown of ThreadPool is initiated, previously submitted tasks are
* executed, but no new tasks will be accepted.
*
* @author AnkitMittal
* Copyright (c), AnkitMittal .JavaMadeSoEasy.com
* All Contents are copyrighted and must not be reproduced in any form.
*/
class ThreadPool {
private BlockingQueueCustom<Runnable> taskQueue;

/*
* Once pool shutDown will be initiated, poolShutDownInitiated will become true.
*/
private boolean poolShutDownInitiated = false;
/* Constructor of ThreadPool
* nThreads= is a number of threads that exist in ThreadPool.
* nThreads number of threads are created and started. *
*/
public ThreadPool(int nThreads){
taskQueue = new LinkedBlockingQueueCustom<Runnable>(nThreads);
//Create and start nThreads number of threads.
for(int i=1; i<=nThreads; i++){
ThreadPoolsThread threadPoolsThread=new ThreadPoolsThread(taskQueue,this);
threadPoolsThread.setName("Thread-"+i);
System.out.println("Thread-"+i +" created in ThreadPool.");
threadPoolsThread.start(); //start thread
}

/**
* Execute the task, task must be of Runnable type.
*/
public synchronized void execute(Runnable task) throws Exception{
if(this.poolShutDownInitiated)
throw new Exception("ThreadPool has been shutDown, no further tasks can be added");

/*
* Add task in sharedQueue,
* and notify all waiting threads that task is available.
*/
System.out.println("task has been added.");
this.taskQueue.put(task);
}
public boolean isPoolShutDownInitiated() {
return poolShutDownInitiated;
}
/**
* Initiates shutdown of ThreadPool, previously submitted tasks
* are executed, but no new tasks will be accepted.
*/
public synchronized void shutdown(){
this.poolShutDownInitiated = true;
System.out.println("ThreadPool SHUTDOWN initiated.");
}
}
/**
* These threads are created and started from constructor of ThreadPool class.
*/
class ThreadPoolsThread extends Thread {
private BlockingQueueCustom<Runnable> taskQueue;
private ThreadPool threadPool;
public ThreadPoolsThread(BlockingQueueCustom<Runnable> queue,
ThreadPool threadPool){
taskQueue = queue;
this.threadPool=threadPool;
}
public void run() {
try {
/*
* ThreadPool's threads will keep on running
* until ThreadPool is not shutDown (shutDown will interrupt thread) and
* taskQueue contains some unExecuted tasks.
*/
while (true) {
System.out.println(Thread.currentThread().getName()
+" is READY to execute task.");
/*ThreadPool's thread will take() task from sharedQueue
* only if tasks are available else
* waits for tasks to become available.
*/
Runnable runnable = taskQueue.take();
System.out.println(Thread.currentThread().getName()
+" has taken task.");
//Now, execute task with current thread.
runnable.run();

System.out.println(Thread.currentThread().getName()
+" has EXECUTED task.");

/*
* 1) Check whether pool shutDown has been initiated or not,
* if pool shutDown has been initiated and
* 2) taskQueue does not contain any
* unExecuted task (i.e. taskQueue's size is 0 )
* than interrupt() the thread.
*/
if(this.threadPool.isPoolShutDownInitiated()
&& this.taskQueue.size()==0){
this.interrupt();
/*
* Interrupting basically sends a message to the thread
* indicating it has been interrupted but it doesn't cause
* a thread to stop immediately,
*
* if sleep is called, thread immediately throws
* InterruptedException
*/
Thread.sleep(1);
}
}
} catch (Exception e) {
System.out.println(Thread.currentThread().getName()+" has been STOPPED.");
}
}
}
/**
* Task class which implements Runnable.
*/
class Task implements Runnable{
@Override
public void run() {
try {
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName()
+" is executing task.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
/**
* Test ThreadPool.
*/
public class ThreadPoolTest{
public static void main(String[] args) throws Exception {
ThreadPool threadPool=new ThreadPool(2); //create 2 threads in ThreadPool
Runnable task=new Task();
threadPool.execute(task);
threadPool.execute(task);

threadPool.shutdown();

}
/*OUTPUT
Thread-1 created in ThreadPool.
Thread-2 created in ThreadPool.
Thread-1 is READY to execute task.
Thread-2 is READY to execute task.
task has been added.
task has been added.
Thread-1 has taken task.
Thread-2 has taken task.
ThreadPool SHUTDOWN initiated.
Thread-1 is executing task.
Thread-1 has EXECUTED task.
Thread-1 has been STOPPED.
Thread-2 is executing task.
Thread-2 has EXECUTED task.
Thread-2 has been STOPPED.
*/

Let’s discuss output in detail, to get better understanding of ThreadPool program >
Note : I have mentioned output in green text.

Total number of thread created in ThreadPool was 2.


Thread-1 created in ThreadPool.
Till now Thread-1 have been created.
Thread-2 created in ThreadPool.
Till now Thread-2 have been created.

Thread-1 is READY to execute task.


Thread-1 have entered run() method and taskQueue’s size is 0. So its waiting for task to become available.
Thread-2 is READY to execute task.
Thread-2 have entered run() method and taskQueue’s size is 0. So its waiting for task to become available.

task has been added.


execute() method of ThreadPool is called by main thread, it internally calls put() method on taskQueue to add tasks. Once
tasks is available all waiting threads are notified that task is available.

task has been added.


execute() method of ThreadPool is called by main thread, it internally calls put() method on taskQueue to add tasks. Once
tasks is available all waiting threads are notified that task is available.

Thread-1 has taken task.


As waiting Thread-1 has been notified it takes task.

Thread-2 has taken task.


As waiting Thread-2 has been notified it takes task.

ThreadPool SHUTDOWN initiated.


threadPool.shutdown() is called by main thread, previously submitted tasks are executed, but no new tasks will be accepted.

Thread-1 is executing task.


Thread-1 is executing task, it’s in run() method of Task class (shutdown was initiated, but previously submitted tasks are
executed ).

Thread-1 has EXECUTED task.


Thread-1 has executed task.

Thread-1 has been STOPPED.


Thread-1 has been stopped.

Thread-2 is executing task.


Thread-2 is executing task, it’s in run() method of Task class.

Thread-2 has EXECUTED task.


Thread-2 has executed task.

Thread-2 has been STOPPED.


Thread-2 has been stopped.

ThreadLocal in multithreading in java - methods and usage with program


This question will test your command in multi threading, can you really create some perfect multithreading application or
not. ThreadLocal is a class which provides thread-local variables.

What is ThreadLocal ?
ThreadLocal is a class which provides thread-local variables. Every thread has its own ThreadLocal value that makes
ThreadLocal value threadsafe as well.

For how long Thread holds ThreadLocal value?


Thread holds ThreadLocal value till it hasn’t entered dead state.

Can one thread see other thread’s ThreadLocal value?


No, thread can see only it’s ThreadLocal value.

Are ThreadLocal variables thread safe. Why?


Yes, ThreadLocal variables are thread safe. As every thread has its own ThreadLocal value and one thread can’t see other
threads ThreadLocal value.

Application of ThreadLocal?
1. ThreadLocal are used by many web frameworks for maintaining some context (may be session or request)
related value.
o In any single threaded application, same thread is assigned for every request made to same action, so
ThreadLocal values will be available in next request as well.
o In multi threaded application, different thread is assigned for every request made to same action, so
ThreadLocal values will be different for every request.

2. When threads have started at different time they might like to store time at which they have started. So, thread’s
start time can be stored in ThreadLocal.
Creating ThreadLocal >

private ThreadLocal<String> threadLocal = new ThreadLocal<String>();

We will create instance of ThreadLocal. ThreadLocal is a generic class, i will be using String to demonstrate threadLocal.
All threads will see same instance of ThreadLocal, but a thread will be able to see value which was set by it only.

How thread set value of ThreadLocal >

threadLocal.set( new Date().toString());

Thread set value of ThreadLocal by calling set(“”) method on threadLocal.


How thread get value of ThreadLocal >

threadLocal.get()

Thread get value of ThreadLocal by calling get() method on threadLocal.

How thread remove value of ThreadLocal >

threadLocal.remove();

Thread can remove value of ThreadLocal by calling remove() method on threadLocal. Once value has been removed get()
method will return null.

Full Program on how to use ThreadLocal >

import java.util.Date;
public class ThreadLocalUsage {
public static class MyRunnable implements Runnable {
private ThreadLocal<String> threadLocal = new
ThreadLocal<String>();

@Override
public void run() {

threadLocal.set(new Date().toString());

try {
Thread.sleep(4000);
} catch (InterruptedException e) { e.printStackTrace(); }

System.out.println(Thread.currentThread().getName()+
" start time = "+threadLocal.get());
}
}
public static void main(String[] args) throws InterruptedException {
MyRunnable myRunnable = new MyRunnable();
Thread thread1 = new Thread(myRunnable,"Thread-1");
Thread thread2 = new Thread(myRunnable,"Thread-2");
thread1.start();
Thread.sleep(1000); //Start thread-2 after 1 second.
thread2.start();
}
}

/*OUTPUT
Thread-1 start time = Sun Mar 08 4:08:43 IST 2015
Thread-2 start time = Sun Mar 08 4:08:44 IST 2015
*/

In the program, Thread-1 started and after 1 second Thread-2 also started.
Thread-1 called threadLocal.set(new Date().toString()) and set the threadLocal value i.e. value when thread was started
and then went for sleep.
Than, Thread-2 called threadLocal.set(new Date().toString()) and set the threadLocal value i.e. value when thread was
started and then went for sleep.
When both the threads waked up they called threadLocal.get() and we saw that both threads were having different
threadLocal value i.e. time at which they started.
Conclusion : Thread-1 and Thread-2 were having different threadLocal value.

Was either of threads able to see each others threadLocal value?


No, neither of thread was not able to see each other value, as threadLocal value printed by both threads was different.

Setting up ThreadLocal initial value >


By overriding initialValue() method of ThreadLocal we can set initial value of ThreadLocal.
import java.util.Date;
public class ThreadLocalInitialValue {
public static class MyRunnable implements Runnable {
private ThreadLocal<String> threadLocal = new ThreadLocal<String>()
{
@Override
protected String initialValue() {
return (new Date().toString());
}
};

@Override
public void run() {
System.out.println(Thread.currentThread().getName()+
" start time = "+threadLocal.get());
}
}
public static void main(String[] args) throws InterruptedException {
MyRunnable myRunnable = new MyRunnable();
Thread thread1 = new Thread(myRunnable,"Thread-1");
thread1.start();
}
}
/*OUTPUT
Thread-1 start time = Sun Mar 08 4:25:20 IST 2015
*/

What will happen if ThreadLocal was replaced with some other object in above program>
If ThreadLocal is replaced with some other object let’s say String than both the threads will hold same value for threadLocal.

private ThreadLocal<String> threadLocal = new ThreadLocal<String>();

Replace ThreadLocal with String.

private String threadLocal = "";

import java.util.Date;
public class ThreadLocalReplaceWithString {
public static class MyRunnable implements Runnable {
private String threadLocal = new String("");

@Override
public void run() {

threadLocal= new Date().toString();

try {
Thread.sleep(4000);
} catch (InterruptedException e) { e.printStackTrace(); }

System.out.println(Thread.currentThread().getName()+
" start time = "+threadLocal);
}
}
public static void main(String[] args) throws InterruptedException {
MyRunnable myRunnable = new MyRunnable();
Thread thread1 = new Thread(myRunnable,"Thread-1");
Thread thread2 = new Thread(myRunnable,"Thread-2");
thread1.start();
Thread.sleep(1000); //Start thread-2 after 1 second.
thread2.start();

}
}
/*OUTPUT
Thread-1's start time = Sun Mar 08 4:33:00 IST 2015
Thread-2's start time = Sun Mar 08 4:33:00 IST 2015
*/
ThreadLocal was replaced with String.
Thread-1’s threadLocal value was overridden by Thread-2’s threadLocal value. So, threadLocal printed same start time for
both threads.

Busy Spin - What is busy spin? Consumer Producer problem with busy spin and solution to busy spin in java.

What is busy spin?


When one thread loops continuously waiting for another thread to signal.

Performance point of view - Busy spin is very bad from performance point of view, because one thread keeps on looping
continuously ( and consumes CPU) waiting for another thread to signal.

Solution to busy spin -


We must use sleep() or wait() and notify() method. Using wait() is better option.

Why using wait() and notify() is much better option to solve busy spin?
Because in case when we use sleep() method, thread will wake up again and again after specified sleep time until boolean
variable is true. But, in case of wait() thread will wake up only when when notified by calling notify() or notifyAll(), hence
end up consuming CPU in best possible manner

Program - Consumer Producer problem with busy spin >

Note: In below program, Producer will allow consumer to consume only when 10 products have been produced (i.e. when
production is over)

Consumer thread continuously execute (busy spin) in while loop (till productionInProcess is true) and wait for producer
thread to get over. Once producer thread has ended it will make boolean variable productionInProcess false and busy spin
will be over.
while(this.prod.productionInProcess){
System.out.println("BUSY SPIN - Consumer waiting for production to get over");
}

But how performance is impacted in this program?


Performance is impacted because consumer thread is continuously executing and unnecessarily consuming CPU. It would
have been better if consumer would have called wait() and waited until being notified by producer. So, consumer thread
consumes CPU unnecessarily and didn’t allow producer to utilize complete CPU better performance.

import java.util.ArrayList;
/* Producer will allow consumer to
* consume only when 10 products have been produced (i.e. when production is over).
*/
class Producer implements Runnable{

boolean productionInProcess;
ArrayList<Integer> list;
Producer(){
productionInProcess=true; //initially Producer will be producing, so
//make this productionInProcess true.
list=new ArrayList<Integer>();
}

@Override
public void run(){

for(int i=1;i<=10;i++){ //Producer will produce 10 products


list.add(i);
System.out.println("Producer is still Producing, Produced : "+i);

try{
Thread.sleep(500);
}catch(InterruptedException e){e.printStackTrace();}

}
productionInProcess=false; // Once production is over, make
//this productionInProcess false.
//Production is over, consumer can consume.

}
class Consumer extends Thread{
Producer prod;

Consumer(Producer obj){
prod=obj;
}

public void run(){


/*
* consumer will continuously loop until productionInProcess is true.
*/
while(this.prod.productionInProcess){ //BUSY SPIN
System.out.println("BUSY SPIN - Consumer waiting for production to get over.");
}

/*productionInProcess is false means production is over,


consumer will start consuming. */
System.out.println("Production is over, consumer can consume.");
int productSize=this.prod.list.size();
for(int i=0;i<productSize;i++)
System.out.println("Consumed : "+ this.prod.list.remove(0) +" ");

}
public class BusySpin{
public static void main(String args[]){

Producer prod=new Producer();


Consumer cons=new Consumer(prod);

Thread prodThread=new Thread(prod,"prodThread");


Thread consThread=new Thread(cons,"consThread");

prodThread.start(); //start producer thread.


consThread.start(); //start consumer thread.

}
}
If we execute this program we will note in output that "BUSY SPIN - Consumer waiting for production to get over.” is
printed several times.

Solution to busy spin using wait() and notify() methods-

Executor and ExecutorService framework in java - Detailed explanation with full program

Executor and ExecutorService are used for following purposes in java >
 creating thread,
 starting threads,
 managing whole life cycle of Threads.
Executor creates pool of threads and manages life cycle of all threads in it in java.

1) What is java.util.concurrent.Executor in java >


java.util.concurrent.Executor interface defines very important execute() method which executes command in java.

1.1) Executor methods in java >

void execute(Runnable command)


Executes the given command. Executor may execute command in a
 new thread, or
 in a pooled thread, or
 in the calling thread
at the discretion of the Executor implementation in java.

2) java.util.concurrent.ExecutorService in java >


java.util.concurrent.ExecutorService interface extends Executor interface in java.
An Executor interface provides following type of methods in java >
 methods for managing termination and
 methods that can produce a Future for tracking progress of tasks.

An Executor that provides methods to manage termination and methods that can produce a Future for tracking progress of
one or more asynchronous tasks in java.

2.1) ExecutorService methods in java >

boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException


Blocks until one of the following things happen >
 all tasks have completed execution after a shutdown request, or
 specified timeout elapses, or
 current thread is interrupted.

<T> Future<T> submit(Callable<T> task)


Submits a task for execution.
Method returns a Future which represents pending results of the task.
Once task is completed Future's get method will return the task's result.

<T> Future<T> submit(Runnable task, T result)


Submits a Runnable task for execution.
Method returns a Future which represents that task. Once task is completed Future's get method will return result.

Future<?> submit(Runnable task)


Submits a Runnable task for execution.
Method returns a Future which represents that task. Once task is completed Future's get method will return null in java.

void shutdown()
Initiates shutdown of executor, previously submitted tasks are executed, but no new tasks will be accepted in java.

List<Runnable> shutdownNow()
 executor shutDowns immediately,
 all actively executing tasks are stopped,
 awaiting tasks will never execute, and
 method returns list all tasks that were awaiting execution in java.

boolean isTerminated()
Method returns true if all tasks have completed following shut down in java.

<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException


Executes the given tasks and returns a list of Futures holding their status in java.

3) Example/Program to demonstrate usage of java.util.concurrent.Executor and java.util.concurrent.ExecutorService in


thread concurrency in java >

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class MyRunnable implements Runnable {
int taskNumber;
MyRunnable(int taskNumber) {
this.taskNumber = taskNumber;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()
+ " executing task no " + taskNumber);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

public class ExecutorServiceExample {


//nThreads number of threads will be created and started in executor.
//here we will create 2 threads.
private static int nThreads = 2;

//nTasks number of tasks will be executed.


//here we will execute 10 tasks.
private static int nTasks = 10;
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(nThreads);
System.out.println("executor created with 2 threads.");

System.out.println("2 threads in executor will be used for executing 10 tasks. "


+ "So, at a time only 2 tasks will be executed");
for (int i = 1; i <= nTasks; i++) {
Runnable task = new MyRunnable(i);
executor.execute(task);
}
/*
* Initiates shutdown of executor, previously submitted tasks are
* executed, but no new tasks will be accepted.
*/
executor.shutdown();
System.out.println("executor has been shutDown.");
}
}
/*OUTPUT
executor created with 2 threads.
2 threads in executor will be used for executing 10 tasks. So, at a time only 2 tasks will be executed
pool-1-thread-1 executing task no 1
pool-1-thread-2 executing task no 2
executor has been shutDown.
pool-1-thread-1 executing task no 3
pool-1-thread-2 executing task no 4
pool-1-thread-1 executing task no 5
pool-1-thread-2 executing task no 6
pool-1-thread-1 executing task no 7
pool-1-thread-2 executing task no 8
pool-1-thread-2 executing task no 9
pool-1-thread-1 executing task no 10
*/

3.1) Let’s discuss output in detail, to get better understanding of Executor and ExecutorService usage in program in java >
Note : I have mentioned output in green text.

executor created with 2 threads.


ExecutorService executor = Executors.newFixedThreadPool(nThreads), creates
2 threads in executor.

2 threads in executor will be used for executing 10 tasks. So, at a time only 2 tasks will be executed
2 created threads in executor will be used for executing 10 tasks. So, at a time only 2 tasks will be executed.

pool-1-thread-1 executing task no 1


pool-1-thread-2 executing task no 2
executor has been shutDown.
executor.shutdown(), was called but all previously submitted tasks will be executed.

pool-1-thread-1 executing task no 3


pool-1-thread-2 executing task no 4
pool-1-thread-1 executing task no 5
pool-1-thread-2 executing task no 6
pool-1-thread-1 executing task no 7
pool-1-thread-2 executing task no 8
pool-1-thread-2 executing task no 9
pool-1-thread-1 executing task no 10

If we analyze output at runtime we will notice that at a time only 2 tasks were executed.

We must shutdown executor after executing tasks.

So far in this thread concurrency tutorial we have learned what is Executor and ExecutorService framework in java with
program and examples. Now we will learn what are Future and Callable in java.

4) java.util.concurrent.Future<V> in java
Future interface provides methods in java >
 for returning result of computation, wait until computation is not completed and
 for cancelling the computation in between in java.

Future Methods in java >

V get() throws InterruptedException, ExecutionException;


Method returns the result of computation, method waits for computation to complete.
V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
Method waits for at most timeout time for computation to complete, and then returns the result, if available.

cancel method
method cancels the task.

5) java.util.concurrent.Callable<V> in java
Callable interface provides method for computing a result and returning that computed result or throws an exception if
unable to do so
Any class implementing Callable interface must override call() method.

what type of results Callable’s call() method can return in java?


The Callable<V> is a generic interface, so its call method can return generic result spcified by V.

V call() throws Exception;


method for computing a result.
Method returns computed result or throws an exception if unable to do so.

How Callable and Future are related in java?


If you submit a Callable object to an Executor returned object is of Future type.

Future<Double> futureDouble=executor.submit(new SquareDoubleCallable(2.2));

This Future object can check the status of a Callable call’s method and wait until Callable’s call() method is not completed.

SquareDoubleCallable is a class which implements Callable.

6) Example/Program to demonstrate usage of java.util.concurrent.Callable and java.util.concurrent.Future in thread


concurrency in java >
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
class SumIntegerCallable implements Callable<Integer> {
Integer n;
SumIntegerCallable(Integer n) {
this.n = n;
}
@Override
public Integer call() throws Exception {
Integer sum = 0;
for (int i = 0; i <= n; i++) {
sum += i;
}
return sum;
}
}
class SquareDoubleCallable implements Callable<Double> {
Double n;
SquareDoubleCallable(Double n) {
this.n = n;
}
@Override
public Double call() throws Exception {
return n*n;
}
}
public class CallableFutureExample {
private static final int NTHREDS = 10;
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executor = Executors.newFixedThreadPool(NTHREDS);
Future<Integer> futureInteger=executor.submit(new SumIntegerCallable(4));
Future<Double> futureDouble=executor.submit(new SquareDoubleCallable(2.2));

System.out.println("SumIntegerCallable has returned > "+futureInteger.get());


System.out.println("SquareDoubleCallable has returned > "+futureDouble.get());

executor.shutdown();
}
}
/*OUTPUT
SumIntegerCallable has returned > 10
SquareDoubleCallable has returned > 4.840000000000001
*/

In the above program - we submit a Callable object to an Executor and returned object was of Future type.

7) Similarity and differences between java.util.concurrent.Callable and java.lang.Runnable in java?

Similarity between java.util.concurrent.Callable and java.lang.Runnable?


Instances of class which implements callable are executed by another thread.

Difference between java.util.concurrent.Callable and java.lang.Runnable?


Class implementing Callable interface must override call() method. call() method returns computed result or throws an
exception if unable to do so.
Class implementing Runnable interface must override run() method.
A Runnable does not return a result and can neither throw a checked exception.

8) Using <T> Future<T> submit(Runnable task, T result) and Future<?> submit(Runnable task) in program in java >

Let me brief you about both methods again-

<T> Future<T> submit(Runnable task, T result)


Submits a Runnable task for execution. Method returns a Future which represents that task. Once task is completed Future's
get method will return the given result.

Future<?> submit(Runnable task)


Submits a Runnable task for execution. Method returns a Future which represents that task. Once task is completed Future's
get method will return null.

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("MyRunnable's run()");

}
}
public class SubmitRunnableExample {
private static final int NTHREDS = 10;
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executor = Executors.newFixedThreadPool(NTHREDS);
Future<Integer> futureInteger=executor.submit(new MyRunnable(), 1);
System.out.println("futureInteger.get() > "+futureInteger.get());

Future<?> future=executor.submit(new MyRunnable());


System.out.println("future.get() > "+future.get());
}
}
/*OUTPUT
MyRunnable's run()
futureInteger.get() > 1
MyRunnable's run()
future.get() > null
*/

Let’s analyze output -


when executor.submit(new MyRunnable(), 1) was called, it internally called call() method and on successful completion of
MyRunnable’s run() method, futureInteger.get() returned 1, i.e. second parameter passed in submit method.
This type of submit method could be handy when in certain scenarios we want to return status of task.

when executor.submit(new MyRunnable()) was called, it internally called call() method and on successful completion of
MyRunnable’s run() method, futureInteger.get() returned null.

9) Differences between execute() and submit() method of executor framework in thread concurrency in java >

execute() method submit() method

execute() method is defined in submit() method is defined in ExecutorService interface in java.


Executor interface in java.

It can be used for executing It can be used for executing runnable task or callable task, submitted callable
runnable task. returns future and Future's get method will return the task's result.

submit method has 3 forms >


Signature of execute method is > <T> Future<T> submit(Callable<T> task)
Submits a callable task for execution.
void execute(Runnable task)
Method returns a Future which represents pending results of the task.
Once task is completed Future's get method will return the task's result in java.

<T> Future<T> submit(Runnable task, T result)


Submits a Runnable task for execution.
Method returns a Future which represents that task. Once task is completed
Future's get method will return result.

Future<?> submit(Runnable task)


Submits a Runnable task for execution.
Method returns a Future which represents that task. Once task is completed
Future's get method will return null in java.

So, in this thread concurrency tutorial we learned what is java.util.concurrent.Executor and


java.util.concurrent.ExecutorService framework in java with program and examples. We learned important methods of
Executor like execute and methods of ExecutorService like submit, awaitTermination and shutdown in java. We learned how
to use Executor and ExecutorService framework in thread concurrency in java.
We also learned what are java.util.concurrent.Future and java.util.concurrent.Callable in thread concurrency in java.
Semaphore in java - with real world application and programs

In this thread concurrency tutorial we will learn what is java.util.concurrent.Semaphore in java with program and examples.
We will learn about Semaphore constructors, what is permits, Semaphore’s important method like acquire and release in
thread concurrency in java. We will learn Application of Semaphore in real world (for solving Producer Consumer problem)

1. What is java.util.concurrent.Semaphore in java?


A semaphore controls access to a shared resource by using permits in java.
 If permits are greater than zero, then semaphore allow access to shared resource.
 If permits are zero or less than zero, then semaphore does not allow access to shared resource.
These permits are sort of counters, which allow access to the shared resource. Thus, to access the resource, a thread must be
granted a permit from the semaphore.
In next post we will learn Implementation of custom/own Semaphore in java.

1.1) Semaphore has 2 constructors in java >


 Semaphore(int permits)
permits is the initial number of permits available.
This value can be negative, in which case releases must occur before any acquires will be granted, permits is
number of threads that can access shared resource at a time.
If permits is 1, then only one threads that can access shared resource at a time.

 Semaphore(int permits, boolean fair)


permits is the initial number of permits available.
This value can be negative, in which case releases must occur before any acquires will be granted.
By setting fair to true, we ensure that waiting threads are granted a permit in the order in which they
requested access.

1.2) Semaphore’s acquire( ) method has 2 forms in java:


 void acquire( ) throws InterruptedException
Acquires a permit if one is available and decrements the number of available permits by 1.
If no permit is available then the current thread waits until one of the following things happen >
>some other thread calls release() method on this semaphore or,
>some other thread interrupts the current thread.

 void acquire(int permits) throws InterruptedException


Acquires permits number of permits if available and decrements the number of available permits by permits.
If permits number of permits are not available then the current thread becomes dormant until one of the following
things happens -
>some other thread calls release() method on this semaphore and available permits become equal to permits or,
>some other thread interrupts the current thread.

1.3) Semaphore’s release( ) method has 2 forms in java:


 void release( )
Releases a permit and increases the number of available permits by 1.
For releasing lock by calling release() method it’s not mandatory that thread must have acquired permit by calling acquire()
method.
 void release(int permits)
Releases permits number of permits and increases the number of available permits by permits.
For releasing lock by calling release(int permits) method it’s not mandatory that thread must have acquired permit by
calling acquire()/acquire(int permit) method.

2) Program to demonstrate usage of Semaphore in java >


import java.util.concurrent.Semaphore;
/** Copyright (c), AnkitMittal JavaMadeSoEasy.com */
public class SemaphoreExample {
static int SharedValue=0;

public static void main(String[] args) {


Semaphore semaphore=new Semaphore(1);
System.out.println("Semaphore with 1 permit has been created");

IncrementThread incrementThread=new IncrementThread(semaphore);


new Thread(incrementThread,"incrementThread").start();

DecrementThread decrementThread=new DecrementThread(semaphore);


new Thread(decrementThread,"decrementThread").start();

}
}

class IncrementThread implements Runnable{


Semaphore semaphore;

public IncrementThread(Semaphore s) {
semaphore=s;
}

public void run(){


System.out.println(Thread.currentThread().getName()+
" is waiting for permit");
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName()+
" has got permit");

for(int i=0;i<5;i++){
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+
" > "+SemaphoreExample.SharedValue++);
}

} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println(Thread.currentThread().getName()+
" has released permit");
semaphore.release();

}
class DecrementThread implements Runnable{
Semaphore semaphore;
public DecrementThread(Semaphore s){
semaphore=s;
}

public void run(){


System.out.println(Thread.currentThread().getName()+
" is waiting for permit");

try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName()+
" has got permit");

for(int i=0;i<5;i++){
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+
" >"+SemaphoreExample.SharedValue--);
}

} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println(Thread.currentThread().getName()+
" has released permit");
semaphore.release();

}
/*OUTPUT

Semaphore with 1 permit has been created


incrementThread is waiting for permit
incrementThread has got permit
decrementThread is waiting for permit
incrementThread > 0
incrementThread > 1
incrementThread > 2
incrementThread > 3
incrementThread > 4
incrementThread has released permit
decrementThread has got permit
decrementThread >5
decrementThread >4
decrementThread >3
decrementThread >2
decrementThread >1
decrementThread has released permit
*/

Let’s discuss output in detail, to get better understanding of Semaphore usage in program in java >
Note : I have mentioned output in green text.

Semaphore with 1 permit has been created


Initially, Semaphore with 1 permit is created (permit=1).
incrementThread is waiting for permit
incrementThread has entered run() method of IncrementThread class and is waiting for permit. (permit=1), as permit is 1
thread could soon get permit to access shared resource i.e. SemaphoreExample.SharedValue

incrementThread has got permit


incrementThread has got permit. (Now, permit=0).

decrementThread is waiting for permit


decrementThread has entered run() method of DecrementThread class and is waiting for permit (permit=0), as permit is 0
thread got to wait for permit to become 1 to access shared resource i.e. SemaphoreExample.SharedValue

incrementThread > 0
incrementThread > 1
incrementThread > 2
incrementThread > 3
incrementThread > 4
incrementThread continues to increment SemaphoreExample.SharedValue

incrementThread has released permit


incrementThread has released permit by calling release() method on semaphore. (Now, permit=1).

decrementThread has got permit


decrementThread has got permit. (Now, permit=0).

decrementThread >5
decrementThread >4
decrementThread >3
decrementThread >2
decrementThread >1
incrementThread continues to decrement SemaphoreExample.SharedValue

decrementThread has released permit


decrementThread has released permit by calling release() method on semaphore. (Now, permit=1).

3) Application of Semaphore in real world (for solving Producer Consumer problem in java) >

Semaphore can be used for implementing Producer Consumer pattern in java.

But how Semaphore can be used for implementing Producer Consumer pattern?

Semaphore on producer is created with permit =1. So, that producer can get the permit to produce.
Semaphore on consumer is created with permit =0. So, that consumer could wait for permit to consume. [because
initially producer hasn’t produced any product]

Producer gets permit by calling semaphoreProducer.acquire() and starts producing, after producing it calls
semaphoreConsumer.release(). So, that consumer could get the permit to consume.
semaphoreProducer.acquire();
System.out.println("Produced : "+i);
semaphoreConsumer.release();

Consumer gets permit by calling semaphoreConsumer.acquire() and starts consuming, after consuming it calls
semaphoreProducer.release(). So, that producer could get the permit to produce.

semaphoreConsumer.acquire();
System.out.println("Consumed : "+i);
semaphoreProducer.release();

For more detailed information on how Semaphore can be used for implementing Producer Consumer pattern, please refer my
next tutorial.

4) Program - If permits are 0, then acquire() method can acquire lock only when release() method is called in java.

import java.util.concurrent.Semaphore;
public class SemaphoreExample {
public static void main(String[] args) {
Semaphore semaphore=new Semaphore(0);
new Thread(new MyRunnable(semaphore),"Thread-1").start();

}
}
class MyRunnable implements Runnable{
Semaphore semaphore;

public MyRunnable(Semaphore semaphore) {


this.semaphore=semaphore;
}

public void run(){


System.out.println(Thread.currentThread().getName()+
" is waiting for permit");
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName()+
" has got permit");

} catch (InterruptedException e) {
e.printStackTrace();
}

}
/*OUTPUT
Thread-1 is waiting for permit
*/

In above program, we have initialized Semaphore with 0 permits.


So, acquire() method is waiting for some other thread to call release() method for acquiring lock.
release() method has not been called in above program because it was just for demonstration purpose to give you further
in depth explanation of Semaphore.
So, in this thread concurrency tutorial we learned what is java.util.concurrent.Semaphore in java with program and
examples. We learned about java.util.concurrent.Semaphore constructors, what is permits, java.util.concurrent.Semaphore’s
important method like acquire and release in thread concurrency in java. We also learned Application of Semaphore in real
world (for solving Producer Consumer problem)

Semaphore used for implementing Producer Consumer pattern in java


In last post we learned how to use Semaphores in java. Now, let’s use Semaphore for implementing Producer Consumer
pattern

1) Logic behind using Semaphore for implementing Producer Consumer pattern >
Semaphore on producer is created with permit =1. So, that producer can get the permit to produce.
Semaphore on consumer is created with permit =0. So, that consumer could wait for permit to consume. [because
initially producer hasn’t produced any product]

Producer gets permit by calling semaphoreProducer.acquire() and starts producing, after producing it calls
semaphoreConsumer.release(). So, that consumer could get the permit to consume.

semaphoreProducer.acquire();
System.out.println("Produced : "+i);
semaphoreConsumer.release();

Consumer gets permit by calling semaphoreConsumer.acquire() and starts consuming, after consuming it calls
semaphoreProducer.release(). So, that producer could get the permit to produce.

semaphoreConsumer.acquire();
System.out.println("Consumed : "+i);
semaphoreProducer.release();

2) Program to demonstrate usage of Semaphore for implementing Producer Consumer pattern >
import java.util.concurrent.Semaphore;

/** Copyright (c), AnkitMittal JavaMadeSoEasy.com */


public class ConsumerProducer{

public static void main(String[] args) {


Semaphore semaphoreProducer=new Semaphore(1);
Semaphore semaphoreConsumer=new Semaphore(0);
System.out.println("semaphoreProducer permit=1 | semaphoreConsumer permit=0");

Producer producer=new Producer(semaphoreProducer,semaphoreConsumer);


Consumer consumer=new Consumer(semaphoreConsumer,semaphoreProducer);

Thread producerThread = new Thread(producer, "ProducerThread");


Thread consumerThread = new Thread(consumer, "ConsumerThread");
producerThread.start();
consumerThread.start();
}
}
/**
* Producer Class.
*/
class Producer implements Runnable{

Semaphore semaphoreProducer;
Semaphore semaphoreConsumer;
public Producer(Semaphore semaphoreProducer,Semaphore semaphoreConsumer) {
this.semaphoreProducer=semaphoreProducer;
this.semaphoreConsumer=semaphoreConsumer;
}
public void run() {
for(int i=1;i<=5;i++){
try {
semaphoreProducer.acquire();
System.out.println("Produced : "+i);
semaphoreConsumer.release();

} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* Consumer Class.
*/
class Consumer implements Runnable{
Semaphore semaphoreConsumer;
Semaphore semaphoreProducer;

public Consumer(Semaphore semaphoreConsumer,Semaphore semaphoreProducer) {


this.semaphoreConsumer=semaphoreConsumer;
this.semaphoreProducer=semaphoreProducer;
}
public void run() {

for(int i=1;i<=5;i++){
try {
semaphoreConsumer.acquire();
System.out.println("Consumed : "+i);
semaphoreProducer.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}
/*OUTPUT
semaphoreProducer permit=1 | semaphoreConsumer permit=0
Produced : 1
Consumed : 1
Produced : 2
Consumed : 2
Produced : 3
Consumed : 3
Produced : 4
Consumed : 4
Produced : 5
Consumed : 5
*/

Let’s discuss output in detail, to get better understanding of how we have used Semaphore for implementing Producer
Consumer pattern >
Note : (I have mentioned output in green text and it’s explanation is given in line immediately followed by it)
semaphoreProducer permit=1 | semaphoreConsumer permit=0
semaphoreProducer created with permit=1. So, that producer can get the permit to produce |
semaphoreConsumer created with permit=0. So, that consumer could wait for permit to consume.

semaphoreProducer.acquire() is called, Producer has got the permit and it can produce [Now, semaphoreProducer permit=0]
Produced : 1 [as producer has got permit, it is producing]
semaphoreConsumer.release() is called, Permit has been released on semaphoreConsumer means consumer can consume
[Now, semaphoreConsumer permit=1]

semaphoreConsumer.acquire() is called, Consumere has got the permit and it can consume [Now, semaphoreConsumer
permit=0]
Consumed : 1 [as consumer has got permit, it is consuming]
semaphoreProducer.release() is called, Permit has been released on semaphoreProducer means producer can produce [Now,
semaphoreProducer permit=1]

Produced : 2
Consumed : 2
Produced : 3
Consumed : 3
Produced : 4
Consumed : 4
Produced : 5
Consumed : 5

Summary >
In previous thread concurrency tutorial we learned what is java.util.concurrent.Semaphore in java. And in this thread
concurrency tutorial we learned application of Semaphore in real world (for solving Producer Consumer problem in java).

Question 104. What is Serialization in java?

Let’s start by understanding what is Serialization, it’s most basic question which you will have to answer almost in each and every java
interview.
Serialization is process of converting object into byte stream.
Serialized object (byte stream) can be:
>Transferred over network.
>Persisted/saved into file.
>Persisted/saved into database.
Once, object have been transferred over network or persisted in file or in database, we could deserialize the object and retain its state as it is
in which it was serialized.

Q105 . Difference between Externalizable and Serialization interface ?

Difference between Externalizable and Serialization interface in java

Q106. How can you avoid certain member variables of class from getting Serialized?
Mark member variables as static or transient, and those member variables will no more be a part of Serialization.

Q107. What is serialVersionUID? What will be impact of not defining serialVersionUID in class?

This is one my favourite question, The serialization at runtime associates with each serializable class a version number, called a
serialVersionUID, which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for
that object that are compatible with respect to serialization.
If we don’t define serialVersionUID in the class, and any modification is made in class, then we won’t be able to deSerialize our class
because serialVersionUID generated by java compiler for modified class will be different from old serialized object . And
deserialization process will end up throwing java.io.InvalidClassException (because of serialVersionUID mismatch)

Q108. What are compatible and incompatible changes in Serialization process?

compatible and incompatible changes in Serialization and deSerialization process in java

Q109. What will happen if one the member of class does not implement Serializable interface (Important)?
This is classy question which will check your in depth knowledge of Serialization concepts. If any of the member does not implement
Serializable than NotSerializableException is thrown. Now, let’s see a program.
Q110. What will happen if we have used List, Set and Map as member of class?
This question which will check your in depth knowledge of Serialization and Java Api’s. ArrayList, HashSet and HashMap implements
Serializable interface, so if we will use them as member of class they will get Serialized and DeSerialized as well. Now, let’s see a program.

Question 111. Is constructor of class called during DeSerialization process?


This question which will check your in depth knowledge of Serialization and constructor chaining concepts. It depends on whether our
object has implemented Serializable or Externalizable.
If Serializable has been implemented - constructor is not called during DeSerialization process.
But, if Externalizable has been implemented - constructor is called during DeSerialization process.

Question 112. Is constructor of super class called during DeSerialization process of subclass?
Again your basic java concepts will be tested over here. It is depends on whether our superclass has implemented Serializable or not.
If superclass has implemented Serializable - constructor is not called during DeSerialization process.
If superclass has not implemented Serializable - constructor is called during DeSerialization process.

Q113. How you can avoid Deserialization process creating another instance of Singleton class?
This is another classy and very important question which will check your in depth knowledge of Serialization and Singleton concepts. I’ll
prefer you must understand this concept in detail. We can simply use readResolve() method to return same instance of class, rather than
creating a new one.

private Object readResolve() throws ObjectStreamException


{
return INSTANCE;
}

Q114. How can subclass avoid Serialization if its superClass has implemented Serialization interface ?
If superClass has implemented Serializable that means subclass is also Serializable (as subclass always inherits all features from its
parent class), for avoiding Serialization in sub-class we can define writeObject() method and throw NotSerializableException().
private void writeObject(ObjectOutputStream os) throws NotSerializableException
{
throw new NotSerializableException("This class cannot be Serialized");
}

Q115. Are primitive types part of serialization process?


Yes, primitive types are part of serialization process. Interviewer tends to check your basic java concepts over here.

Q116. Name few methods of Object class?


wait(), notify() and notifyAll()
equals and hashcode
clone()
toString()

Atomic operations in java - AtomicInteger, AtomicLong, AtomicBoolean

In this thread concurrency tutorial we will learn what are Atomic operations in java with program and examples. We will learn how to
perform Atomic operations in thread concurrency in java. We will learn about different atomic classes like AtomicInteger, AtomicLong
and AtomicBoolean in java.

1) Are Classes found in java.util.concurrent.atomic are thread safe in java?


Java provides some classes in java.util.concurrent.atomic which offers an alternative to the other synchronization. We can use these
classes without any explicit synchronization in multithreading environment, because any operation done on these classes is thread safe in
java.

2) Classes found in java.util.concurrent.atomic are >


 AtomicInteger - AtomicInteger provides you with int value that is updated atomically,
 AtomicLong - AtomicLong provides you with long value that is updated atomically, and
 AtomicBoolean - AtomicBoolean provides you with boolean value that is updated atomically.

3) Why Classes like AtomicByte, AtomicShort, AtomicFloat, AtomicDouble and AtomicCharacter are not found in java (till java 8)
>

AtomicByte, AtomicShort, AtomicFloat, AtomicDouble and AtomicCharacter are present in java (till java 8) because these primitive types
like byte, short, float, double are not used too much as compared to int and long in java. So, there is no point of making concurrent classes
on top of these primitive types. Although this does not conclude to any concrete reason of their absence in java. You never know they might
be introduced in later versions of java.
We will learn important methods of AtomicInteger like getAndSet, incrementAndGet, getAndAdd, getAndIncrement,
decrementAndGet, getAndDecrement and how to use them in thread concurrency in java.

1) What is java.util.concurrent.atomic.AtomicInteger in java ?


java.util.concurrent.atomic.AtomicInteger provides you with int value that is updated atomically. i.e. we can use these classes without any
explicit synchronization in multithreading environment, because any operation done on these classes is thread safe.

Example >
AtomicInteger atomicInteger =new
AtomicInteger();
We have created a new AtomicInteger and it is initialized to 0.
Example >
AtomicInteger atomicInteger =new
AtomicInteger(11);
We have created a new AtomicInteger and it is initialized to 11.

1.2) AtomicInteger important Methods in java >

 int get()
method returns the current value in java

Example >
AtomicInteger atomicInteger =new
AtomicInteger(11);
atomicInteger.get();
Method will return 11.

 void set(int newValue)


Sets to newValue.

Example >
AtomicInteger atomicInteger =new
AtomicInteger(11);
atomicInteger.set(12);
Method will set return atomicInteger to 12.

 int getAndSet(int newValue)


Sets to newValue and returns the old value.

Example >
AtomicInteger atomicInteger =new
AtomicInteger(11);
atomicInteger.getAndSet(12);
Method will set return atomicInteger to 12. And return 11.

 boolean compareAndSet(int expect, int update)

Compare with expect, if equal, set to update and return true.


Example >
AtomicInteger atomicInteger =new
AtomicInteger(11);
atomicInteger.compareAndSet(11, 12);
Now, in call to compareAndSet method first parameter [i.e. 11] is equal to original value, so method will set AtomicInteger to 12.
And returns true if value was successfully set.

1.3) Addition methods of AtomicInteger >


 int addAndGet(int value)
adds value to the current value. And return updated value.

Example >
AtomicInteger atomicInteger =new
AtomicInteger(11);
atomicInteger.addAndGet(4);
adds 4 to the current value. And return 15.

 int incrementAndGet()
increments current value by 1. And return updated value.

Example >
AtomicInteger atomicInteger =new
AtomicInteger(11);
atomicInteger.incrementAndGet();
increments current value by 1. And return 12.

 int getAndAdd(int value)


Method return current value. And adds value to the current value.
Example >
AtomicInteger atomicInteger =new
AtomicInteger(11);
atomicInteger.getAndAdd(4);
Method return 11. And adds 4 to 11.

 int getAndIncrement()
Method return current value. And increments current value by 1.
Example >
AtomicInteger atomicInteger =new
AtomicInteger(11);
atomicInteger.getAndIncrement();
Method return 11. And increments 11 by 1.

1.4) Subtraction methods of AtomicInteger >


 int decrementAndGet()
decrements current value by 1. And return updated value.

Example >
AtomicInteger atomicInteger =new
AtomicInteger(11);
atomicInteger.decrementAndGet();
decrements current value by 1. And return 10.

 int getAndDecrement()
Method return current value. And decrements current value by 1.
Example >
AtomicInteger atomicInteger =new
AtomicInteger(11);
atomicInteger.getAndDecrement();
Method return 11. And decrements 11 by 1.
2) Example/Program to demonstrate usage of java.util.concurrent.atomic.AtomicInteger in java>
package AtomicInteger;
import java.util.concurrent.atomic.AtomicInteger;
class MyRunnable implements Runnable{

public void run(){


for(int i=0;i<2;i++){
System.out.println("ThreadName="+Thread.currentThread().getName()
+" > "+ AtomicIntegerExample.sharedAtomicInteger.incrementAndGet());
}

}
}
public class AtomicIntegerExample {
//Create a new AtomicInteger and is initialized to 0.
static AtomicInteger sharedAtomicInteger =new AtomicInteger();

public static void main(String...args) throws InterruptedException{


MyRunnable runnable=new MyRunnable();
Thread thread1=new Thread(runnable,"Thread-1");
Thread thread2=new Thread(runnable,"Thread-2");
thread1.start();
thread2.start();

Thread.sleep(1000); //delay to ensure Thread-1 and Thread-2 finish


System.out.println("After completion of both threads, "
+ "sharedAtomicInteger = "+sharedAtomicInteger);
}
}
/*OUTPUT
ThreadName=Thread-1 > 1
ThreadName=Thread-2 > 2
ThreadName=Thread-1 > 3
ThreadName=Thread-2 > 4
After completion of both threads, sharedAtomicInteger = 4
*/
In the program, a static AtomicInteger is created with name sharedAtomicInteger and is initialized to 0. Then, Thread-1 and Thread-2
atomically increments sharedAtomicInteger inside run( ) method using incrementAndGet() method [incrementAndGet() method
increments current value by 1. And return updated value].
Here, sharedAtomicInteger being AtomicInteger prevents two threads from writing to it at the same time.

2.1) Occasionally output may be different >


/*OUTPUT
ThreadName=Thread-2 > 1
ThreadName=Thread-2 > 3
ThreadName=Thread-1 > 2
ThreadName=Thread-1 > 4
After completion of both threads, sharedAtomicInteger = 4
*/

sharedAtomicInteger is incremented atomically, but sysout statements have executed out of order.
3) Program to show Consequences of using Integer in place of AtomicInteger in java >
class MyRunnable implements Runnable{

public void run(){


for(int i=0;i<2;i++){

System.out.println("ThreadName="+Thread.currentThread().getName()
+" > "+
++sharedIntegerExample.sharedInteger);
}

}
}
/**
* Main class
*/
public class sharedIntegerExample {

//Create a new Integer and initialize with 0.


static Integer sharedInteger =new Integer(0);

public static void main(String...args) throws InterruptedException{


MyRunnable runnable=new MyRunnable();
Thread thread1=new Thread(runnable,"Thread-1");
Thread thread2=new Thread(runnable,"Thread-2");
thread1.start();
thread2.start();

Thread.sleep(1000); //delay to ensure Thread-1 and Thread-2 finish


System.out.println("After completion of both threads, "
+ "sharedInteger = "+sharedInteger);
}
}
/*OUTPUT
ThreadName=Thread-2 > 1
ThreadName=Thread-1 > 1
ThreadName=Thread-1 > 3
ThreadName=Thread-2 > 2
After completion of both threads, sharedInteger = 3
*/

Integer class is not thread safe so two threads updated sharedInteger out of order.
So at end of program sharedInteger’s value was 3, whereas it should have been 4 because sharedInteger was initialized to 0 and was
incremented 4 times.

Executor and ExecutorService framework in java - Detailed explanation with full program

Executor and ExecutorService are used for following purposes in java >
 creating thread,
 starting threads,
 managing whole life cycle of Threads.
Executor creates pool of threads and manages life cycle of all threads in it in java.

1) What is java.util.concurrent.Executor in java >


java.util.concurrent.Executor interface defines very important execute() method which executes command in java.

1.1) Executor methods in java >

void execute(Runnable command)


Executes the given command. Executor may execute command in a
 new thread, or
 in a pooled thread, or
 in the calling thread
at the discretion of the Executor implementation in java.

2) java.util.concurrent.ExecutorService in java >


java.util.concurrent.ExecutorService interface extends Executor interface in java.
An Executor interface provides following type of methods in java >
 methods for managing termination and
 methods that can produce a Future for tracking progress of tasks.
An Executor that provides methods to manage termination and methods that can produce a Future for tracking progress of one or more
asynchronous tasks in java.

2.1) ExecutorService methods in java

<T> Future<T> submit(Callable<T> task)


Submits a task for execution.
Method returns a Future which represents pending results of the task.
Once task is completed Future's get method will return the task's result.

<T> Future<T> submit(Runnable task, T result)


Submits a Runnable task for execution.
Method returns a Future which represents that task. Once task is completed Future's get method will return result.

Future<?> submit(Runnable task)


Submits a Runnable task for execution.
Method returns a Future which represents that task. Once task is completed Future's get method will return null in java.

void shutdown()
Initiates shutdown of executor, previously submitted tasks are executed, but no new tasks will be accepted in java.

boolean isTerminated()
Method returns true if all tasks have completed following shut down in java.

<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks) throws InterruptedException


Executes the given tasks and returns a list of Futures holding their status in java.

3) Example/Program to demonstrate usage of java.util.concurrent.Executor and java.util.concurrent.ExecutorService in thread concurrency


in java >

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class MyRunnable implements Runnable {
int taskNumber;
MyRunnable(int taskNumber) {
this.taskNumber = taskNumber;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName()
+ " executing task no " + taskNumber);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

public class ExecutorServiceExample {


//nThreads number of threads will be created and started in executor.
//here we will create 2 threads.
private static int nThreads = 2;

//nTasks number of tasks will be executed.


//here we will execute 10 tasks.
private static int nTasks = 10;
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(nThreads);
System.out.println("executor created with 2 threads.");
System.out.println("2 threads in executor will be used for executing 10 tasks. "
+ "So, at a time only 2 tasks will be executed");
for (int i = 1; i <= nTasks; i++) {
Runnable task = new MyRunnable(i);
executor.execute(task);
}
/*
* Initiates shutdown of executor, previously submitted tasks are
* executed, but no new tasks will be accepted.
*/
executor.shutdown();
System.out.println("executor has been shutDown.");
}
}
/*OUTPUT
executor created with 2 threads.
2 threads in executor will be used for executing 10 tasks. So, at a time only 2 tasks will be
executed
pool-1-thread-1 executing task no 1
pool-1-thread-2 executing task no 2
executor has been shutDown.
pool-1-thread-1 executing task no 3
pool-1-thread-2 executing task no 4
pool-1-thread-1 executing task no 5
pool-1-thread-2 executing task no 6
pool-1-thread-1 executing task no 7
pool-1-thread-2 executing task no 8
pool-1-thread-2 executing task no 9
pool-1-thread-1 executing task no 10
*/

3.1) Let’s discuss output in detail, to get better understanding of Executor and ExecutorService usage in program in java >
Note : I have mentioned output in green text.

executor created with 2 threads.


ExecutorService executor = Executors.newFixedThreadPool(nThreads), creates
2 threads in executor.

2 threads in executor will be used for executing 10 tasks. So, at a time only 2 tasks will be executed
2 created threads in executor will be used for executing 10 tasks. So, at a time only 2 tasks will be executed.

pool-1-thread-1 executing task no 1


pool-1-thread-2 executing task no 2
executor has been shutDown.
executor.shutdown(), was called but all previously submitted tasks will be executed.

pool-1-thread-1 executing task no 3


pool-1-thread-2 executing task no 4
pool-1-thread-1 executing task no 5
pool-1-thread-2 executing task no 6
pool-1-thread-1 executing task no 7
pool-1-thread-2 executing task no 8
pool-1-thread-2 executing task no 9
pool-1-thread-1 executing task no 10

If we analyze output at runtime we will notice that at a time only 2 tasks were executed.
We must shutdown executor after executing tasks.
So far in this thread concurrency tutorial we have learned what is Executor and ExecutorService framework in java with program and
examples. Now we will learn what are Future and Callable in java.

4) java.util.concurrent.Future<V> in java
Future interface provides methods in java >
 for returning result of computation, wait until computation is not completed and
 for cancelling the computation in between in java.

Future Methods in java >

V get() throws InterruptedException, ExecutionException;


Method returns the result of computation, method waits for computation to complete.

V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;


Method waits for at most timeout time for computation to complete, and then returns the result, if available.

cancel method
method cancels the task.

5) java.util.concurrent.Callable<V> in java
Callable interface provides method for computing a result and returning that computed result or throws an exception if unable to do so
Any class implementing Callable interface must override call() method.

what type of results Callable’s call() method can return in java?


The Callable<V> is a generic interface, so its call method can return generic result spcified by V.
V call() throws Exception;
method for computing a result.
Method returns computed result or throws an exception if unable to do so.

How Callable and Future are related in java?


If you submit a Callable object to an Executor returned object is of Future type.

Future<Double> futureDouble=executor.submit(new
SquareDoubleCallable(2.2));

This Future object can check the status of a Callable call’s method and wait until Callable’s call() method is not completed.

SquareDoubleCallable is a class which implements Callable.

6) Example/Program to demonstrate usage of java.util.concurrent.Callable and java.util.concurrent.Future in thread concurrency in java >
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
class SumIntegerCallable implements Callable<Integer> {
Integer n;
SumIntegerCallable(Integer n) {
this.n = n;
}
@Override
public Integer call() throws Exception {
Integer sum = 0;
for (int i = 0; i <= n; i++) {
sum += i;
}
return sum;
}
}
class SquareDoubleCallable implements Callable<Double> {
Double n;
SquareDoubleCallable(Double n) {
this.n = n;
}
@Override
public Double call() throws Exception {
return n*n;
}
}
public class CallableFutureExample {
private static final int NTHREDS = 10;
public static void main(String[] args) throws InterruptedException, ExecutionException
{
ExecutorService executor = Executors.newFixedThreadPool(NTHREDS);
Future<Integer> futureInteger=executor.submit(new SumIntegerCallable(4));
Future<Double> futureDouble=executor.submit(new SquareDoubleCallable(2.2));

System.out.println("SumIntegerCallable has returned > "+futureInteger.get());


System.out.println("SquareDoubleCallable has returned > "+futureDouble.get());

executor.shutdown();
}
}
/*OUTPUT
SumIntegerCallable has returned > 10
SquareDoubleCallable has returned > 4.840000000000001
*/

In the above program - we submit a Callable object to an Executor and returned object was of Future type.

7) Similarity and differences between java.util.concurrent.Callable and java.lang.Runnable in java?

Similarity between java.util.concurrent.Callable and java.lang.Runnable?


Instances of class which implements callable are executed by another thread.

Difference between java.util.concurrent.Callable and java.lang.Runnable?


Class implementing Callable interface must override call() method. call() method returns computed result or throws an exception if unable
to do so.
Class implementing Runnable interface must override run() method.
A Runnable does not return a result and can neither throw a checked exception.

8) Using <T> Future<T> submit(Runnable task, T result) and Future<?> submit(Runnable task) in program in java >

Let me brief you about both methods again-

<T> Future<T> submit(Runnable task, T result)


Submits a Runnable task for execution. Method returns a Future which represents that task. Once task is completed Future's get method
will return the given result.

Future<?> submit(Runnable task)


Submits a Runnable task for execution. Method returns a Future which represents that task. Once task is completed Future's get method
will return null.

import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("MyRunnable's run()");

}
}
public class SubmitRunnableExample {
private static final int NTHREDS = 10;
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executor = Executors.newFixedThreadPool(NTHREDS);
Future<Integer> futureInteger=executor.submit(new MyRunnable(), 1);
System.out.println("futureInteger.get() > "+futureInteger.get());

Future<?> future=executor.submit(new MyRunnable());


System.out.println("future.get() > "+future.get());
}
}
/*OUTPUT
MyRunnable's run()
futureInteger.get() > 1
MyRunnable's run()
future.get() > null
*/

Let’s analyze output -


when executor.submit(new MyRunnable(), 1) was called, it internally called call() method and on successful completion of MyRunnable’s
run() method, futureInteger.get() returned 1, i.e. second parameter passed in submit method.
This type of submit method could be handy when in certain scenarios we want to return status of task.

when executor.submit(new MyRunnable()) was called, it internally called call() method and on successful completion of MyRunnable’s
run() method, futureInteger.get() returned null.

9) Differences between execute() and submit() method of executor framework in thread concurrency in java >

execute() method submit() method

execute() method is defined in Executor submit() method is defined in ExecutorService interface in java.
interface in java.

It can be used for executing runnable It can be used for executing runnable task or callable task, submitted callable returns future
task. and Future's get method will return the task's result.

submit method has 3 forms >


Signature of execute method is > <T> Future<T> submit(Callable<T> task)
Submits a callable task for execution.
void execute(Runnable task) Method returns a Future which represents pending results of the task.
Once task is completed Future's get method will return the task's result in java.

<T> Future<T> submit(Runnable task, T result)


Submits a Runnable task for execution.
Method returns a Future which represents that task. Once task is completed Future's get
method will return result.

Future<?> submit(Runnable task)


Submits a Runnable task for execution.
Method returns a Future which represents that task. Once task is completed Future's get
method will return null in java.

CountDownLatch in java - Detailed explanation with full program


In this thread concurrency tutorial we will learn what is java.util.concurrent.CountDownLatch in java with program and examples.
1) What is CountDownLatch in java?
There might be situation where we might like our thread to wait until one or more threads completes certain operation.

A CountDownLatch is initialized with a given count .


count specifies the number of events that must occur before latch is released.
Every time a event happens count is reduced by 1. Once count reaches 0 latch is released.

1.1) CountDownLatch’s constructor in java >


 CountDownLatch(int count)
CountDownLatch is initialized with given count.
count specifies the number of events that must occur before latch is released.
1.2) CountDownLatch’s await() method has 2 forms in java :
 void await( ) throws InterruptedException
Causes the current thread to wait until one of the following things happens-
 latch count has down to reached 0, or
 unless the thread is interrupted.

 boolean await(long timeout, TimeUnit unit)


Causes the current thread to wait until one of the following things happens-
 latch count has down to reached 0,
 unless the thread is interrupted, or
 specified timeout elapses.

1.3) CountDownLatch’s countDown() method in java :


 void countDown( )
Reduces latch count by 1.
If count reaches 0, all waiting threads are released.

1.4) In short about CountDownLatch’s await() and countDown() method in java >
The await() methods block the current threads until the count reaches 0 due to invocations of the countDown() method by some other
thread, after which blocked threads are released.

2) Program to demonstrate usage of CountDownLatch in java >


import java.util.concurrent.CountDownLatch;
class MyRunnable implements Runnable{

CountDownLatch countDownLatch;

MyRunnable(CountDownLatch countDownLatch){
this.countDownLatch=countDownLatch;
}

public void run(){

for(int i=2;i>=0;i--){

countDownLatch.countDown();
System.out.println(Thread.currentThread().getName()+
" has reduced latch count to : "+ i);

try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

public class CountDownLatchTest {

public static void main(String[] args) {


CountDownLatch countDownLatch=new CountDownLatch(3);
System.out.println("CountDownLatch has been created with count=3");

new Thread(new MyRunnable(countDownLatch),"Thread-1").start();

try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}

System.out.println("count has reached zero, "+


Thread.currentThread().getName()+" thread has ended");
}
}
/*OUTPUT
CountDownLatch has been created with count=3
Thread-1 has reduced latch count to : 2
Thread-1 has reduced latch count to : 1
Thread-1 has reduced latch count to : 0
count has reached zero, main thread has ended
*/

2.1) Let’s discuss output in detail, to get better understanding of CountDownLatch usage in program in java >
Note : I have mentioned output in green text.

CountDownLatch has been created with count=3


Initially, CountDownLatch is created with count=3
main thread called countDownLatch.await() and it is waiting for count to become 0.
Thread-1 called countDownLatch.countDown() method. [Now, count=2]
Thread-1 has reduced latch count to : 2

Thread-1 called countDownLatch.countDown() method. [Now, count=1]


Thread-1 has reduced latch count to : 1

Thread-1 called countDownLatch.countDown() method. [Now, count=0]


Thread-1 has reduced latch count to : 0

count has reached zero, main thread has ended


As, count has reached zero, main thread has ended.

2.2) Occasionally, because of threads unpredictable behaviour output may be bit awkward in java >

/*OUTPUT
CountDownLatch has been created with count=3
Thread-1 has reduced latch count to : 2
Thread-1 has reduced latch count to : 1
count has reached zero, main thread has ended
Thread-1 has reduced latch count to : 0
*/

This may happen because as soon as count reaches 0 waiting threads are released. Here, as soon as Thread-1 called countDown() method
third time main thread was released and its sysout statement was executed before Thread-1’s sysout statement.

3) Application of CountDownLatch in real world >


When you go in amusement park, you must have seen on certain rides there is mandate that at least 3 people ( 3 is count) should be there to
take a ride. So, ride keeper (ride keeper is main thread) waits for 3 persons (ride keeper has called await()).
Every time a person comes count is reduced by 1 (let’s say every person is calling countDown() method). Ultimately when 3 persons
reach count becomes 0 & wait for ride keeper comes to end.

CyclicBarrier in java - Detailed explanation with full program


In this thread concurrency tutorial we will learn what is java.util.concurrent.CyclicBarrier in java with program and examples.

1) What is java.util.concurrent.CyclicBarrier in java?


There might be situation where we might have to trigger event only when one or more threads completes certain operation.
2 or more threads wait for each other to reach a common barrier point. When all threads have reached common barrier point (i.e.
when all threads have called await() method) >
 All waiting threads are released, and
 Event can be triggered as well.

1.1) CyclicBarrier’s constructor in java >


 CyclicBarrier(int parties)
New CyclicBarrier is created where parties number of thread wait for each other to reach common barrier point, when all threads
have reached common barrier point, parties number of waiting threads are released.

 CyclicBarrier(int parties, Runnable barrierAction)


New CyclicBarrier is created where parties number of thread wait for each other to reach common barrier point, when all threads
have reached common barrier point, parties number of waiting threads are released and barrierAction (event) is triggered.

1.2) CyclicBarrier’s await() method has 2 forms in java :


 int await() throws InterruptedException, BrokenBarrierException
If the current thread is not the last to arrive(i.e. call await() method) then it waits until one of the following things happens -
 The last thread to call arrive(i,.e. call await() method), or
 Some other thread interrupts the current thread, or
 Some other thread interrupts one of the other waiting threads, or
 Some other thread times out while waiting for barrier, or
 Some other thread invokes reset() method on this cyclicBarrier.

 int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException


If the current thread is not the last to arrive(i.e. call await() method) then it waits until one of the following things happens -
 The last thread to call arrive(i,.e. call await() method), or
 The specified timeout elapses, or
 Some other thread interrupts the current thread, or
 Some other thread interrupts one of the other waiting threads, or
 Some other thread times out while waiting for barrier, or
 Some other thread invokes reset() method on this cyclicBarrier.

2) Program to demonstrate usage of CyclicBarrier in java >


package CyclicBarrier;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierTest {
public static void main(String[] args) {
/*
* Create CountDownLatch with 3 parties, when all 3 parties
* will reach common barrier point CyclicBarrrierEvent will be
* triggered i.e. run() method of CyclicBarrrierEvent will be called
*/
CyclicBarrier cyclicBarrier=new CyclicBarrier(3 ,new CyclicBarrrierEvent());
System.out.println("CountDownLatch has been created with parties=3,"
+ " when all 3 parties will reach common barrier point "
+ "CyclicBarrrierEvent will be triggered");
MyRunnable myRunnable1=new MyRunnable(cyclicBarrier);

//Create and start 3 threads


new Thread(myRunnable1,"Thread-1").start();
new Thread(myRunnable1,"Thread-2").start();
new Thread(myRunnable1,"Thread-3").start();

}
}

class MyRunnable implements Runnable{


CyclicBarrier cyclicBarrier;

MyRunnable(CyclicBarrier cyclicBarrier){
this.cyclicBarrier=cyclicBarrier;
}

@Override
public void run() {

System.out.println(Thread.currentThread().getName() +
" is waiting for all other threads to reach common barrier point");
try {
Thread.sleep(1000);
/*
* when all 3 parties will call await() method (i.e. common barrier point)
* CyclicBarrrierEvent will be triggered and all waiting threads will be released.
*/
cyclicBarrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}

System.out.println("As all threads have reached common barrier point "


+ Thread.currentThread().getName() +
" has been released");
}

class CyclicBarrrierEvent implements Runnable{


public void run() {
System.out.println("As all threads have reached common barrier point "
+ ", CyclicBarrrierEvent has been triggered");
}

}
/*OUTPUT
CountDownLatch has been created with parties=3, when all 3 parties will reach common barrier point CyclicBarrrierEvent will be
triggered
Thread-1 is waiting for all other threads to reach common barrier point
Thread-2 is waiting for all other threads to reach common barrier point
Thread-3 is waiting for all other threads to reach common barrier point
As all threads have reached common barrier point , CyclicBarrrierEvent has been triggered
As all threads have reached common barrier point Thread-1 has been released
As all threads have reached common barrier point Thread-3 has been released
As all threads have reached common barrier point Thread-2 has been released
*/

2.1) Let’s discuss output in detail, to get better understanding of CyclicBarrier usage in program in java >

Note : I have mentioned output in green text.

CountDownLatch has been created with parties=3, when all 3 parties will reach common
barrier point CyclicBarrrierEvent will be triggered
CountDownLatch has been created with parties=3, when Thread-1, Thread-2 and Thread-3 will call await() method, CyclicBarrrierEvent
will be triggered

Thread-1 is waiting for all other threads to reach common barrier point
Thread-1 has called await(), it is waiting for Thread-2 and Thread-3 to call await() method

Thread-2 is waiting for all other threads to reach common barrier point
Thread-1 and Thread-2 has called await(), and they are waiting for Thread-3 to call await() method

Thread-3 is waiting for all other threads to reach common barrier point
Thread-1, Thread-2, and Thread-3 has called await().

As all threads have reached common barrier point , CyclicBarrrierEvent has been triggered
As Thread-1, Thread-2, and Thread-3 has called await(). So, CyclicBarrrierEvent is triggered i.e. run() method of CyclicBarrrierEvent is
called

As all threads have reached common barrier point Thread-1 has been released
As all threads have reached common barrier point Thread-3 has been released
As all threads have reached common barrier point Thread-2 has been released
As Thread-1, Thread-2, and Thread-3 has called await(), all waiting threads are released and completes there execution.

3) Why barrier is called Cyclic in java?


The barrier is called cyclic because CyclicBarrier can be reused after -
 All the waiting threads are released and
 event has been triggered.

When we execute 3 more threads in above program CyclicBarrrierEvent will be triggered again.

//Create and start 3 threads


new Thread(myRunnable1,"Thread-
1").start();
new Thread(myRunnable1,"Thread-
2").start();
new Thread(myRunnable1,"Thread-
3").start();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//Create and start 3 more threads
new Thread(myRunnable1,"Thread-
4").start();
new Thread(myRunnable1,"Thread-
5").start();
new Thread(myRunnable1,"Thread-
6").start();

Output will be -

/*OUTPUT
CountDownLatch has been created with parties=3, when all 3 parties will reach common barrier point CyclicBarrrierEvent will be
triggered
Thread-1 is waiting for all other threads to reach common barrier point
Thread-2 is waiting for all other threads to reach common barrier point
Thread-3 is waiting for all other threads to reach common barrier point
As all threads have reached common barrier point , CyclicBarrrierEvent has been triggered
As all threads have reached common barrier point Thread-3 has been released
As all threads have reached common barrier point Thread-2 has been released
As all threads have reached common barrier point Thread-1 has been released

Thread-4 is waiting for all other threads to reach common barrier point
Thread-5 is waiting for all other threads to reach common barrier point
Thread-6 is waiting for all other threads to reach common barrier point
As all threads have reached common barrier point , CyclicBarrrierEvent has been triggered
As all threads have reached common barrier point Thread-6 has been released
As all threads have reached common barrier point Thread-4 has been released
As all threads have reached common barrier point Thread-5 has been released
*/

4) Application of CyclicBarrier in real world >


Let’s say 10 friends (friends are threads) have planned for picnic on place A (Here place A is common barrier point). And they all
decided to play certain game (game is event) only on everyones arrival at place A. So, all 10 friends must wait for each other to reach place
A before launching event.

Now, when all threads have reached common barrier point (i.e. all friends have reached place A) >
 All waiting threads are released (All friends can play game), and
 Event can be triggered (they will start playing game).

Similarity and Difference between CyclicBarrier and CountDownLatch in Java

1. First let’s discuss Similarity between CyclicBarrier and CountDownLatch in Java. CyclicBarrier and CountDownLatch are similar
because they wait for specified number of thread to reach certain point and make count/parties equal to 0. But ,
for completing wait in CountDownLatch specified number of threads must call countDown() method in Java.
for completing wait in CyclicBarrier specified number of threads must call await() method in Java.

Let’ see there constructor’s in Java >

CountDownLatch(int count) CyclicBarrier(int parties)


CountDownLatch is initialized with given New CyclicBarrier is created where parties number of thread wait for each other to reach
count. common barrier point, when all threads have reached common barrier point, parties
count specifies the number of events that number of waiting threads are released.
must occur before latch is released.

3. This is very important difference between CyclicBarrier and CountDownLatch in java. CyclicBarrier can be awaited
repeatedly, but CountDownLatch can’t be awaited repeatedly. i.e. once count has become 0 cyclicBarrier can be used again but
CountDownLatch cannot be used again in Java.

4. Another important difference between CyclicBarrier and CountDownLatch in java. CyclicBarrier can be used to trigger event,
but CountDownLatch can’t be used to launch event. i.e. once count has become 0 cyclicBarrier can trigger event in Java but
CountDownLatch can’t.

How can cyclicBarrier launch event in java?


CyclicBarrier provides constructor for triggering event in Java.
CyclicBarrier(int parties, Runnable barrierAction)
New CyclicBarrier is created where parties number of thread wait for each other to reach common barrier point, when all threads
have reached common barrier point, parties number of waiting threads are released and barrierAction (event) is triggered in Java.

So, in this thread concurrency tutorial we read what are Similarity and important Difference between CyclicBarrier and
CountDownLatch in Java.

Phaser in java - Detailed explanation with full program


In this thread concurrency tutorial we will learn what is java.util.concurrent.Phaser in java with program and examples. Programs to
demonstrate usage of Phaser in thread concurrency in java.

1) What is java.util.concurrent.Phaser in java?


Phaser is somewhat similar in functionality of CyclicBarrier and CountDownLatch but it provides more flexibility than both of them.

1.1) Registering/deRegistering the parties in java >


In CyclicBarrier we used to register parties in constructor but Phaser provides us flexibility of registering and deRegistering parties at any
time.
For registering parties, we may use any of the following -
 constructors, or
 int register(), or
 bulkRegister().
For deRegistering parties, we may use any of the following -
 arriveAndDeregister()

1.2) Phaser’s constructor in java >


 Phaser()
Creates a new phaser with no initially registered parties.
Any thread which want to use this phaser must register it first.
Phaser is created without parent.
Initially phase number is 0.

 Phaser(int parties)
Creates a new phaser with the parties number of registered unarrived parties.
Phaser is created without parent.
Initially phase number is 0.

 Phaser(Phaser parentPhaser, int parties).


Creates a new phaser with the given parent and number of registered unarrived parties.
When the parent is non-null and the parties is greater than 0, this childPhaser is registered with its parent.
parentPhaser does not terminates until childPhaser is not terminated.

/*
*Creates a new phaser (parentPhaser) with no registered unArrived parties
*/
Phaser parentPhaser = new Phaser();

/*
* Creates a new phaser (childPhaser ) with the given parent &
* no registered unArrived parties.
*/
Phaser childPhaser = new Phaser(parentPhaser,0);

Now, parentPhaser does not terminates until childPhaser is not terminated.

In below section i have shown usage of this constructor with program.

 Phaser(Phaser parent)
Internally it calls phaser(parent,0).

1.3) Phaser methods in java >


int register()
Adds/Registers a new unarrived party to this phaser. It returns >
 the arrival phase number to which this registration applied.
 If phaser has terminated then value is negative and registration has no effect.

If invocation of onAdvance() method is in progress than before returning this method may await its completion.
If this phaser has a parent, and there were no registered parties with this phaser, this child phaser is also registered with its parent.

int bulkRegister(int parties)


Adds parties number of new unarrived parties to this phaser. It returns >
 the arrival phase number to which this registration applied.
 If phaser has terminated then value is negative and registration has no effect.
If invocation of onAdvance() method is in progress than before returning this method may await its completion.
If this phaser has a parent, and parties is greater than 0, and there were no registered parties with this phaser, this child phaser is also
registered with its parent.

int arriveAndDeregister()
Current thread (Party) Arrives and deRegisters from phaser. DeRegistration reduces the number of parties that may be required in future to
move to next phase.

Few small questions might come to your mind.


What do you mean by Adds/Registers a new unarrived party to this phaser ?
When we create instance of MyRunnable, we call phaser.register() in constructor, till that time thread (party) on that instance is not started
(i.e. party has not arrived), we have only registered phaser.

int arrive()
Method is called to signal that party (current thread) has completed a phase. It returns >
o the arrival phase number.
o If phaser has terminated then value is negative.

If any unregistered party calls arrive() than IllegalStateException is thrown,

When does phase completes?


When number of arrivals = number of registered parties.

Does arrive() cause current thread to wait for other registered threads to complete current phase?
No, arrive() method does not cause current thread to wait for other registered threads to complete current phase. That means
current thread can immediately start next phase without waiting for any other registered thread to complete current phase.

int arriveAndAwaitAdvance()
Method is called to signal that party (current thread) has completed a phase.
It returns >
o the arrival phase number.
o If phaser has terminated then value is negative.

If any unregistered party calls arrive() IllegalStateException is thrown,

When does phase completes?


When number of arrivals = number of registered parties.

Now let’s figure out difference between arrive() and arriveAndAwaitAdvance().

Does arriveAndAwaitAdvance() method causes current thread to wait for other registered threads to complete current phase?
Yes, arriveAndAwaitAdvance() method causes current thread to wait for other registered threads to complete current phase.
That means current thread can proceed to next phase only when all other threads have completed current phase (i.e. by calling
arriveAndAwaitAdvance() method).

int getPhase()
getPhase() method can be used for monitoring purposes. Method returns the current phase number.
For first phase it returns 0, for second phase it returns 1 and so on.
boolean isTerminated()
isTerminated() method returns true if phaser has been terminated.

When is phaser terminated?


when calling arriveAndDeregister() methods has caused the number of registered parties to become 0.
Termination can also be triggered when an onAdvance() method returns true.

boolean onAdvance(int phase, int registeredParties)

We can override the onAdvance( ) method to control number of phases which we want to execute.

phase is the current phase number when we enter onAdvance() method i.e. before advancing to next phase.
registeredParties is the current number of registered parties

Everytime before advancing to next phase overriden onAdvance() method is called and returns either true or false.
If method returns true than phaser is terminated ,or
If method returns false than phaser continues and can advance to next phase.

2) Few more quick facts about Phaser >


 Like a CyclicBarrier, a Phaser can be awaited repeatedly in java.

 Maximum number of parties that could be registered with phaser at a time is 65535, if we try to register more parties
IllegalStateException will be thrown in java.

 Phasers may be constructed in tree structures to reduce contention in java.

3) Example/ Program to demonstrate usage of Phaser in java>


import java.util.concurrent.Phaser;
/** Copyright (c), AnkitMittal JavaMadeSoEasy.com */
public class PhaserExample {
public static void main(String[] args) {
/*Creates a new phaser with 1 registered unArrived parties
* and initial phase number is 0
*/
Phaser phaser=new Phaser(1);
System.out.println("new phaser with 1 registered unArrived parties"
+ " created and initial phase number is 0 ");

//Create 3 threads
Thread thread1=new Thread(new MyRunnable(phaser,"first"),"Thread-1");
Thread thread2=new Thread(new MyRunnable(phaser,"second"),"Thread-2");
Thread thread3=new Thread(new MyRunnable(phaser,"third"),"Thread-3");
System.out.println("\n--------Phaser has started---------------");
//Start 3 threads
thread1.start();
thread2.start();
thread3.start();
//get current phase
int currentPhase=phaser.getPhase();
/*arriveAndAwaitAdvance() will cause thread to wait until current phase
* has been completed i.e. until all registered threads
* call arriveAndAwaitAdvance()
*/
phaser.arriveAndAwaitAdvance();
System.out.println("------Phase-"+currentPhase+" has been
COMPLETED----------");
//------NEXT PHASE BEGINS------

currentPhase=phaser.getPhase();
phaser.arriveAndAwaitAdvance();
System.out.println("------Phase-"+currentPhase+" has been
COMPLETED----------");

/* current thread Arrives and deRegisters from phaser.


* DeRegistration reduces the number of parties that may
* be required to advance in future phases.
*/
phaser.arriveAndDeregister();

//check whether phaser has been terminated or not.


if(phaser.isTerminated())
System.out.println("\nPhaser has been terminated");

}
}

class MyRunnable implements Runnable{


Phaser phaser;

MyRunnable(Phaser phaser,String name){


this.phaser=phaser;
this.phaser.register(); //Registers/Add a new unArrived party to this phaser.
System.out.println(name +" - New unarrived party has "
+ "been registered with phaser");
}

@Override
public void run() {
System.out.println(Thread.currentThread().getName() +
" - party has arrived and is working in "
+ "Phase-"+phaser.getPhase());
phaser.arriveAndAwaitAdvance();

//Sleep has been used for formatting output


try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}

//------NEXT PHASE BEGINS------

System.out.println(Thread.currentThread().getName() +
" - party has arrived and is working in "
+ "Phase-"+phaser.getPhase());
phaser.arriveAndAwaitAdvance();

phaser.arriveAndDeregister();
}

}
/*OUTPUT
new phaser with 1 registered unArrived parties created and initial phase number is 0
first - New unarrived party has been registered with phaser
second - New unarrived party has been registered with phaser
third - New unarrived party has been registered with phaser
--------Phaser has started---------------
Thread-1 - party has arrived and is working in Phase-0
Thread-2 - party has arrived and is working in Phase-0
Thread-3 - party has arrived and is working in Phase-0
------Phase-0 has been COMPLETED----------
Thread-3 - party has arrived and is working in Phase-1
Thread-2 - party has arrived and is working in Phase-1
Thread-1 - party has arrived and is working in Phase-1
------Phase-1 has been COMPLETED----------
Phaser has been terminated
*/
3.1) Let’s discuss output in detail, to get better understanding of Phaser usage in program in java >
Note : I have mentioned output in green text.

new phaser with 1 registered unArrived parties created and initial phase number is 0
Phaser phaser=new Phaser(1), Creates a new phaser with 1 registered unArrived parties and initial phase number is 0.

first - New unarrived party has been registered with phaser


second - New unarrived party has been registered with phaser
third - New unarrived party has been registered with phaser
We have created 3 MyRunnable objects and in MyRunnable’s constructor all 3 new unarrived party has been registered with phaser.
--------Phaser has started---------------

main thread has called arriveAndAwaitAdvance() and waiting for another 3 registered parties (Thread-1, Thread-2 and Thread-3) to call
arriveAndAwaitAdvance().

Thread-1 - party has arrived and is working in Phase-0


Thread-1 (party) has called arriveAndAwaitAdvance() and waiting for other 2 registered parties to call arriveAndAwaitAdvance()

Thread-2 - party has arrived and is working in Phase-0


Thread-2 (one more party) has called arriveAndAwaitAdvance() and waiting for other 1 registered party to call arriveAndAwaitAdvance()

Thread-3 - party has arrived and is working in Phase-0


Now, all registered parties have called arriveAndAwaitAdvance(), main thread can resume.

------Phase-0 has been COMPLETED----------


As, all registered parties have called arriveAndAwaitAdvance(), main thread has resumed.

Thread-3 - party has arrived and is working in Phase-1


Thread-2 - party has arrived and is working in Phase-1
Thread-1 - party has arrived and is working in Phase-1

After working in phase-1 all the registered threads calls arriveAndAwaitAdvance() and than calls arriveAndDeregister(), now only main
thread is registered with phaser.

------Phase-1 has been COMPLETED----------

Main thread has called arriveAndAwaitAdvance() and then called arriveAndDeregister(), now there is no thread registered with phaser.

Phaser has been terminated


As, there is no thread registered with phaser now, phaser has terminated.

4) Example/ Program to demonstrate usage of parentPhaser and childPhaser in java >


Program shows that parentPhaser does not terminates until childPhaser is not terminated.

package PhaserParent;
import java.util.concurrent.Phaser;
public class PhaserParentChildTest {
public static void main(String[] args) {
/*
* Creates a new phaser with no registered unArrived parties.
*/
Phaser parentPhaser = new Phaser();

/*
* Creates a new phaser with the given parent &
* no registered unArrived parties.
*/
Phaser childPhaser = new Phaser(parentPhaser,0);

childPhaser.register();

System.out.println("parentPhaser isTerminated :
"+parentPhaser.isTerminated());
System.out.println("childPhaser isTerminated : "+childPhaser.isTerminated());

childPhaser.arriveAndDeregister();
System.out.println("\n--childPhaser has called arriveAndDeregister()-- \n");

System.out.println("parentPhaser isTerminated :
"+parentPhaser.isTerminated());
System.out.println("childPhaser isTerminated : "+childPhaser.isTerminated());

}
}
/* OUTPUT
parentPhaser isTerminated : false
childPhaser isTerminated : false
--childPhaser has called arriveAndDeregister()--
parentPhaser isTerminated : true
childPhaser isTerminated : true
*/

We created a parentPhaser with no registered unArrived parties. Than we created a childPhaser with the given parentPhaser & no registered
unArrived parties.
Then registered childPhaser . Then parentPhaser didn’t terminated until childPhaser was not terminated.

5) Example/ Program to demonstrate usage of how we can override Phaser’s onAdvance method to control number of phase we want to
execute in java>

Let me brief you about boolean onAdvance(int phase, int registeredParties) method.
phase is the current phase number when we enter onAdvance() method i.e. before advancing to next phase.
registeredParties is the current number of registered parties in java.

We can override the onAdvance( ) method to control number of phases which we want to execute in java.

Every Time before advancing to next phase overridden onAdvance() method is called and returns either true or false in java.
If method returns true then phaser is terminated ,or
If method returns false then phaser continues and can advance to next phase.

package PhaserOnAdvance;
import java.util.concurrent.Phaser;
/*
* class extending Phaser
*/
public class PhaserOnAdvanceTest extends Phaser{

public PhaserOnAdvanceTest(int parties) {


super(parties);
System.out.println("new phaser with 1 registered unArrived parties"
+ " created and initial phase number is 0 ");
}

/*
* Every time before advancing to next phase overridden
* onAdvance() method is called and returns either true or false.
*/
@Override
protected boolean onAdvance(int phase, int registeredParties) {

System.out.println("onAdvance() method, current phase="+phase);

/*return true after completing phase-1 or


* if number of registeredParties become 0
*/
if(phase==1 || registeredParties==0){
System.out.println("onAdvance() method, returning true, hence phaser will
terminate");
return true;
}
else{
System.out.println("onAdvance() method, returning false, hence phaser will
continue");
return false;
}
}
public static void main(String[] args) {
//Creates a new phaser with 1 registered unArrived parties and phase-0 created.
PhaserOnAdvanceTest phaser=new PhaserOnAdvanceTest(1);

//Create 3 threads
Thread thread1=new Thread(new MyRunnable(phaser,"first"),"Thread-1");
Thread thread2=new Thread(new MyRunnable(phaser,"second"),"Thread-2");
Thread thread3=new Thread(new MyRunnable(phaser,"third"),"Thread-3");
System.out.println("\n--------Phaser has started---------------");
//Start 3 threads
thread1.start();
thread2.start();
thread3.start();
while(!phaser.isTerminated()){
//get current phase
int currentPhase=phaser.getPhase();
/*arriveAndAwaitAdvance() will cause thread to wait until current phase
* has been completed i.e. until all registered threads
* call arriveAndAwaitAdvance()
*/
phaser.arriveAndAwaitAdvance();
System.out.println("------Phase-"+currentPhase+" has been COMPLETED----------");
}

}
}
class MyRunnable implements Runnable{
Phaser phaser;

MyRunnable(Phaser phaser,String name){


this.phaser=phaser;
this.phaser.register(); //Registers/Add a new unArrived party to this phaser.
System.out.println(name +" - New unarrived party has "
+ "been registered with phaser");
}

@Override
public void run() {

while(!phaser.isTerminated()){

System.out.println(Thread.currentThread().getName() +
" - party has arrived and is working in "
+ "Phase-"+phaser.getPhase());
phaser.arriveAndAwaitAdvance();

//Sleep has been used for formatting output


try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

}
/*OUTPUT
new phaser with 1 registered unArrived parties created and initial phase number is 0
first - New unarrived party has been registered with phaser
second - New unarrived party has been registered with phaser
third - New unarrived party has been registered with phaser
--------Phaser has started---------------
Thread-1 - party has arrived and is working in Phase-0
Thread-2 - party has arrived and is working in Phase-0
Thread-3 - party has arrived and is working in Phase-0
onAdvance() method, current phase=0
onAdvance() method, returning false, hence phaser will continue
------Phase-0 has been COMPLETED----------
Thread-2 - party has arrived and is working in Phase-1
Thread-1 - party has arrived and is working in Phase-1
Thread-3 - party has arrived and is working in Phase-1
onAdvance() method, current phase=1
onAdvance() method, returning true, hence phaser will terminate
------Phase-1 has been COMPLETED----------
*/

5.1) Let’s discuss output in detail, to get better understanding of how we can override Phaser’s onAdvance method to control number of
phase we want to execute in java >
Note : I have mentioned output in green text.

new phaser with 1 registered unArrived parties created and initial phase number is 0
public PhaserOnAdvanceTest(int parties) {
super(parties);
}
Creates a new phaser with 1 registered unArrived parties and initial phase number is 0.

first - New unarrived party has been registered with phaser


second - New unarrived party has been registered with phaser
third - New unarrived party has been registered with phaser
We have created 3 MyRunnable objects and in MyRunnable’s constructor all 3 new unarrived party has been registered with phaser.
--------Phaser has started---------------
main thread has called arriveAndAwaitAdvance() and waiting for other 3 registered parties (Thread-1, Thread-2 and Thread-3) to call
arriveAndAwaitAdvance().

Thread-1 - party has arrived and is working in Phase-0


Thread-1 (party) has called arriveAndAwaitAdvance() and waiting for other 2 registered parties to call arriveAndAwaitAdvance()

Thread-2 - party has arrived and is working in Phase-0


Thread-2 (one more party) has called arriveAndAwaitAdvance() and waiting for another 1 registered party to call arriveAndAwaitAdvance()

Thread-3 - party has arrived and is working in Phase-0


Now, all registered parties have called arriveAndAwaitAdvance(), main thread can resume.

onAdvance() method, current phase=0


Everytime before advancing to next phase overridden onAdvance() method is called and returns either true or false.
Hence, we enter onAdvance() method and current phase is 0

onAdvance() method, returning false, hence phaser will continue


onAdvance() method is returning false, hence phaser will continue
------Phase-0 has been COMPLETED----------
Main thread has called arriveAndAwaitAdvance() and then called arriveAndDeregister(), now there is no thread registered with phaser.

Thread-2 - party has arrived and is working in Phase-1


Thread-1 - party has arrived and is working in Phase-1
Thread-3 - party has arrived and is working in Phase-1
onAdvance() method, current phase=1
Hence, we enter onAdvance() method and current phase is 1
if(phase==1 || registeredParties==0){
return true;
}
In if statement phase==1 will satisfy and phaser will return true.

onAdvance() method, returning true, hence phaser will terminate


onAdvance() method is returning true, hence phaser will terminate.

------Phase-1 has been COMPLETED----------

6) Application of Phaser in real world >


Software process management is done in phases.
 First phase could be requirement gathering,
 second could be software development and
 third could be testing.
Second phase will not start until first is not completed, likewise third phase will not start until second is not completed.

SUMMARY>
In this thread concurrency tutorial we learned what is java.util.concurrent.Phaser in java with program and examples. We also wrote
programs to demonstrate usage of Phaser in thread concurrency in java.

ReEntrantLocks in java - Detailed explanation with full program


In this thread concurrency tutorial we will learn what is java.util.concurrent.locks.Lock and java.util.concurrent.locks.ReEntrantLock in
java with program and examples. We will learn about Lock and ReEntrantLock constructors, example of using Locks in java,
java.util.concurrent.locks.Lock interface important methods in java like lock(), unlock(), tryLock(), tryLock(long timeout, TimeUnit
unit), newCondition(), About java.util.concurrent.locks.Condition interface in java, Program to demonstrate usage of newCondition()
method - solving Producer consumer problem in java, ReentrantLock class in java, ReentrantLock constructor ReentrantLock(),
ReentrantLock(boolean fair), Program to demonstrate usage of ReentrantLock in java, ReentrantLock’s tryLock() method in java,
ReentrantLock’s getQueueLength() method , Application of using ReentrantLock with program in java.

1) What is java.util.concurrent.locks.Lock in java?


The java.util.concurrent.locks.Lock is a interface and its implementations provide more extensive locking operations than can be obtained
using synchronized methods and statements.
A lock helps in controlling access to a shared resource by multiple threads. Only one thread at a time can acquire the lock and
access the shared resource.
If a second thread attempts to acquire the lock on shared resource when it is acquired by another thread, the second thread will wait until the
lock is released. In this way we can achieve synchronization and race conditions can be avoided.
In next post we will learn Implementation of custom/own Lock and ReEntrantLock in java.
Read lock of a ReadWriteLock may allow concurrent access to a shared resource.

2) Example of using Locks in java>


Let's say there is only 1 ticket available in train, and two passengers are trying to book that ticket at same time without any synchronization.
Both passengers might end up booking same ticket, which will create some synchronization problems .If synchronization was there only of
them would have been able to book ticket. Here, locks can be used as an alternate for synchronization.
3) Lock interface important methods in java >

void lock()
Acquires the lock if it is not held by another thread. And sets lock hold count to 1.
If current thread already holds lock then lock hold count is increased by 1.
If the lock is held by another thread then the current thread waits for another thread to release lock.

void unlock()
If the current thread is holding the lock then the lock hold count is decremented by 1. If the lock hold count has reached 0, then the lock is
released.
If lock hold count is still greater than 0 then lock is not released.
If the current thread is not holding the lock then IllegalMonitorStateException is thrown.

boolean tryLock()
Acquires the lock if it is not held by another thread and returns true. And sets lock hold count to 1.
If current thread already holds lock then method returns true. And increments lock hold count by 1.
If lock is held by another thread then method return false.

boolean tryLock(long timeout, TimeUnit unit)


throws InterruptedException
Acquires the lock if it is not held by another thread and returns true. And sets lock hold count to 1.
If current thread already holds lock then method returns true. And increments lock hold count by 1.
If lock is held by another thread then current thread will wait until one of the following things happen -
 Another thread releases lock and the lock is acquired by the current thread, or
 Some other thread interrupts the current thread, or
 The specified timeout elapses .

If the lock is acquired then method returns true. And sets lock hold count to 1.
If specified timeout elapses then method return false.

Condition newCondition()
Method returns a Condition instance to be used with this Lock instance.
Condition instance are similar to using Wait(), notify() and notifyAll() methods.

 IllegalMonitorStateException is thrown if this lock is not held when any of the Condition waiting or signalling methods are
called.

 Lock is released when the condition waiting methods are called and before they return, the lock is reacquired and the lock
hold count restored to what it was when the method was called.

 If a thread is interrupted while waiting then InterruptedException will be thrown and following things will happen -
o the wait will be over, and
o thread's interrupted status will be cleared.

 Waiting threads are signalled in FIFO (first in first out order) order.
 When lock is fair, first lock is obtained by longest-waiting thread.
If lock is not fair, any waiting thread could get lock, at discretion of implementation.

4) About Condition interface in java.


Condition interface is found in java.util.concurrent.locks package.
Condition instance are similar to using Wait(), notify() and notifyAll() methods on object.

Condition important methods in java >


void await()
method is similar to wait() method of object class.
boolean await(long time, TimeUnit unit)
method is similar to wait(long timeout) method of object class.
void signal()
method is similar to notify() method of object class.
void signalAll()
method is similar to notifyAll() method of object class.

Program/ Example to demonstrate usage of newCondition() method - solving Producer consumer problem >

More detailed description of Condition interface with program, see -


ReentrantLock class provides implementation of Lock’s newCondition() method - description and solving producer consumer program
using this method.

5) ReentrantLock class in java >


java.util.concurrent.locks.ReentrantLock is a class which implements Lock interface. It provides some additional capabilities as defined
in Lock interface.

5.1) ReentrantLock constructor in java >


 ReentrantLock()
Creates an instance of ReentrantLock.
This is equivalent to using constructor ReentrantLock(false).

 ReentrantLock(boolean fair)
Creates an instance of ReentrantLock.
When fair is set true, first lock is obtained by longest-waiting thread.
If fair is set false, any waiting thread could get lock, at discretion of implementation.

5.2) ReentrantLock class important methods in java>

ReentrantLock class provides implementation of all Lock interface methods


void lock()
void unlock()
boolean tryLock()
boolean tryLock(long timeout, TimeUnit unit)
Condition newCondition()

5.3) Additional methods provided by ReentrantLock class in java are >

void lockInterruptibly() throws InterruptedException


If current thread already holds lock then method returns true. And increments lock hold count by 1.
If the lock is held by another thread then the current thread waits until one of the following thing happens -
 The lock is acquired by the current thread, or
 Some other thread interrupts the current thread.
As soon as current thread acquires the lock it sets lock hold count to 1.

int getQueueLength()
Method returns number of threads that may be waiting to acquire this lock.
Method is used just for monitoring purposes and not for any kind of synchronization purposes.

boolean isHeldByCurrentThread()
Method returns true if lock is held by current thread. Its similar to Thread.holdsLock() method.

6) Program/ Example to demonstrate usage of ReentrantLock in java >

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockTest {
public static void main(String[] args) {
Lock lock=new ReentrantLock();
MyRunnable myRunnable=new MyRunnable(lock);
new Thread(myRunnable,"Thread-1").start();
new Thread(myRunnable,"Thread-2").start();

}
}

class MyRunnable implements Runnable{


Lock lock;
public MyRunnable(Lock lock) {
this.lock=lock;
}
public void run(){

System.out.println(Thread.currentThread().getName()
+" is Waiting to acquire lock");

lock.lock();
System.out.println(Thread.currentThread().getName()
+" has acquired lock.");

try {
Thread.sleep(5000);

System.out.println(Thread.currentThread().getName()
+" is sleeping.");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()
+" has released lock.");

lock.unlock();
}
}
/*OUTPUT
Thread-1 is Waiting to acquire lock
Thread-2 is Waiting to acquire lock
Thread-1 has acquired lock.
Thread-1 is sleeping.
Thread-1 has released lock.
Thread-2 has acquired lock.
Thread-2 is sleeping.
Thread-2 has released lock.
*/

6.1) Let’s discuss output in detail, to get better understanding of ReentrantLock usage in program in java >
Note : I have mentioned output in green text.

Thread-1 is Waiting to acquire lock


Thread-2 is Waiting to acquire lock
Thread-1 and Thread-2 are waiting to acquire lock.

Thread-1 has acquired lock.


Thread-1 has acquired lock by calling lock() method. (Now lock hold count=1)
Thread-2 has also called lock() method, but it will have to wait until lock hold count becomes 0. (lock hold count will become 0 when
Thread-1 will call unlock() method)

Thread-1 is sleeping.
Thread-1 has released lock.
Thread-1 has released lock by calling unlock() method. (Now lock hold count=0)

Thread-2 has acquired lock.


Thread-2 has acquired lock by calling lock() method. (Now lock hold count=1)

Thread-2 is sleeping.
Thread-2 has released lock.
Thread-2 has released lock by calling unlock() method. (Now lock hold count=0)

7) Program/ Example to demonstrate usage of ReentrantLock’s tryLock() method in java >

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockTryLockTest {
public static void main(String[] args) {
Lock lock=new ReentrantLock();
MyRunnable myRunnable=new MyRunnable(lock);
new Thread(myRunnable,"Thread-1").start();
new Thread(myRunnable,"Thread-2").start();

}
}

class MyRunnable implements Runnable{

Lock lock;
public MyRunnable(Lock lock) {
this.lock=lock;
}

public void run(){

System.out.println(Thread.currentThread().getName()
+" is Waiting to acquire lock");

if(lock.tryLock()){
System.out.println(Thread.currentThread().getName()
+" has acquired lock.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}

}
else{
System.out.println(Thread.currentThread().getName()
+" didn't got lock.");

}
}
}
/*OUTPUT
Thread-1 is Waiting to acquire lock
Thread-2 is Waiting to acquire lock
Thread-1 has acquired lock.
Thread-2 didn't got lock.
*/

7.1) Let’s discuss output in detail, to get better understanding of ReentrantLock’s tryLock() method usage in program in java >
Note : I have mentioned output in green text.

Thread-1 is Waiting to acquire lock


Thread-2 is Waiting to acquire lock

Thread-1 has acquired lock.


thread-1 called lock.tryLock(), lock was available. So, thread-1 acquired lock, method returned true and entered if block.

Thread-2 didn't got lock.


thread-2 called lock.tryLock(), lock wasn’t available. So, method returned false and entered else block.

8) Program/ Example to demonstrate usage of ReentrantLock’s getQueueLength() method in java >

import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockGetQueuedThreadTest {
public static void main(String[] args) {
ReentrantLock lock=new ReentrantLock();
MyRunnable myRunnable=new MyRunnable(lock);
new Thread(myRunnable,"Thread-1").start();
new Thread(myRunnable,"Thread-2").start();
new Thread(myRunnable,"Thread-3").start();
}
}

class MyRunnable implements Runnable{

ReentrantLock lock;
public MyRunnable(ReentrantLock lock) {
this.lock=lock;
}

public void run(){

System.out.println(Thread.currentThread().getName()
+" is Waiting to acquire lock");

lock.lock();
System.out.println(Thread.currentThread().getName()
+" has acquired lock.");

try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(">>>>--- getQueueLength = "+lock.getQueueLength()+"---<<<<");

System.out.println(Thread.currentThread().getName()
+" has released lock.");

lock.unlock(); //read explanation for 5sec


}
}
/*OUTPUT
Thread-1 is Waiting to acquire lock
Thread-3 is Waiting to acquire lock
Thread-2 is Waiting to acquire lock
Thread-1 has acquired lock.
>>>>--- getQueueLength = 2---<<<<
Thread-1 has released lock.
Thread-3 has acquired lock.
>>>>--- getQueueLength = 1---<<<<
Thread-3 has released lock.
Thread-2 has acquired lock.
>>>>--- getQueueLength = 0---<<<<
Thread-2 has released lock.
*/

8.1) Let’s discuss output in detail, to get better understanding of ReentrantLock’s getQueueLength() method usage in program in java >
Thread-1 is Waiting to acquire lock
Thread-3 is Waiting to acquire lock
Thread-2 is Waiting to acquire lock
Thread-1 has acquired lock.
>>>>--- getQueueLength = 2---<<<<
At this moment Thread-2 and Thread-3 were waiting for lock.
Thread-1 has released lock.
Thread-3 has acquired lock.
>>>>--- getQueueLength = 1---<<<<
At this moment Thread-2 was waiting for lock.
Thread-3 has released lock.
Thread-2 has acquired lock.
>>>>--- getQueueLength = 0---<<<<
At this moment no thread was waiting for lock.
Thread-2 has released lock.

9) Application of using ReentrantLock with program in java >

Reentrantlocks can be used to solve Train-passenger problem when 2 passengers try to book train ticket, when only 1 ticket is
available.
Program to show that with Reentrantlocks no problems will happen when 2 passengers try to book train ticket, when only 1 ticket was
available >
import java.util.concurrent.locks.Lock;
public class ReentrantLockTest {
public static void main(String[] args) {
Lock lock=new ReentrantLock();
MyRunnable myRunnable=new MyRunnable(lock);
new Thread(myRunnable,"Passenger1 Thread").start();
new Thread(myRunnable,"Passenger2 Thread").start();

}
}

class MyRunnable implements Runnable{

int ticketsAvailable=1;
Lock lock;
public MyRunnable(Lock lock) {
this.lock=lock;
}

public void run(){

System.out.println("Waiting to book ticket for : "+


Thread.currentThread().getName());

lock.lock();

if(ticketsAvailable>0){
System.out.println("Booking ticket for : "+
Thread.currentThread().getName());

//Let's say system takes some time in booking ticket


//(here we have taken 1 second time)
try{
Thread.sleep(1000);
}catch(Exception e){}

ticketsAvailable--;
System.out.println("Ticket BOOKED for : "+
Thread.currentThread().getName());
System.out.println("currently ticketsAvailable = "+ticketsAvailable);
}
else{
System.out.println("Ticket NOT BOOKED for : "+
Thread.currentThread().getName());
}

lock.unlock(); //read explanation for 5sec


}
}
/*OUTPUT
Waiting to book ticket for : Passenger1 Thread
Waiting to book ticket for : Passenger2 Thread
Booking ticket for : Passenger1 Thread
Ticket BOOKED for : Passenger1 Thread
currently ticketsAvailable = 0
Ticket NOT BOOKED for : Passenger2 Thread
*/

9.1) OUTPUT ANALYZATION of above program in java>


Waiting to book ticket for : Passenger1 Thread
Waiting to book ticket for : Passenger2 Thread
first Passenger1 Thread and Passenger2 Thread waited to book tickets.

Booking ticket for : Passenger1 Thread


Than, Passenger1 Thread acquired lock [by calling lock.lock() ], but Passenger2 Thread wasn’t able to acquire lock and was waiting for
Passenger1 Thread to release lock.

Ticket BOOKED for : Passenger1 Thread


Passenger1 Thread was successfully able to book ticket and reduce the available ticket count to 0. Than it released object lock [by calling
lock.unlock() ]
currently ticketsAvailable = 0

Ticket NOT BOOKED for : Passenger2 Thread


Than, Passenger1 Thread acquired lock [by calling lock.lock() ], but available ticket count at that time was 0 so it wasn’t able to book
ticket.

10) What will happen if thread that holds lock again calls lock() method in java?

Initially lock hold count = 0. When thread calls lock() method lock hold count is set to one (Now, lock hold count =1). If same thread
again calls lock() method lock hold count is incremented by one (Now, lock hold count =2).

Now some other thread will be able to acquire lock only when lock hold count is 0. Thread will have to wait until lock hold count becomes
0.

When same thread calls unlock() method lock hold count is decremented by one (Now, lock hold count =1) and thread won’t release
lock. If same thread again calls unlock() method lock hold count is decremented by one (Now, lock hold count =0), thread will release
lock and some other thread can acquire lock.

10.1) Program/ Example to show what will happen if thread that holds lock again calls lock() method in java >

import java.util.concurrent.locks.Lock;
public class ReentrantLockTest {
public static void main(String[] args) {
Lock lock=new ReentrantLock();
MyRunnable myRunnable=new MyRunnable(lock);
new Thread(myRunnable,"Thread-1").start();
new Thread(myRunnable,"Thread-2").start();

}
}

class MyRunnable implements Runnable{

Lock lock;
public MyRunnable(Lock lock) {
this.lock=lock;
}

public void run(){

System.out.println(Thread.currentThread().getName()
+" is Waiting to acquire lock");

lock.lock();
System.out.println();
System.out.println(Thread.currentThread().getName()
+" has called lock(), lockHoldCount=1 ");

lock.lock();
System.out.println(Thread.currentThread().getName()
+" has called lock(), lockHoldCount=2 ");

System.out.println(Thread.currentThread().getName()
+" is about to call unlock(), lockHoldCount will become 1 ");
lock.unlock();

System.out.println(Thread.currentThread().getName()
+" is about to call unlock(), lockHoldCount will become 0 ");
lock.unlock();

}
}
/*OUTPUT
Thread-2 is Waiting to acquire lock
Thread-1 is Waiting to acquire lock
Thread-2 has called lock(), lockHoldCount=1
Thread-2 has called lock(), lockHoldCount=2
Thread-2 is about to call unlock(), lockHoldCount will become 1
Thread-2 is about to call unlock(), lockHoldCount will become 0
Thread-1 has called lock(), lockHoldCount=1
Thread-1 has called lock(), lockHoldCount=2
Thread-1 is about to call unlock(), lockHoldCount will become 1
Thread-1 is about to call unlock(), lockHoldCount will become 0
*/

Difference between synchronized and ReentrantLock in java


There are following important differences between synchronized and ReEntrantLocks in java >

Synchronized ReentrantLock

Does not provide any fair locks in java. provides fair locks, when lock is fair - first lock is obtained by longest-waiting
thread in java.

Constructor to provide fairness -

ReentrantLock(boolean fair)
Creates an instance of ReentrantLock.
When fair is set true, first lock is obtained by longest-waiting thread.
If fair is set false, any waiting thread could get lock, at discretion of
implementation.

Does not provide tryLock() method or its Provide tryLock() method. If lock is held by another thread then method
functionality. Thread always waits for lock in return false in java.
java.

boolean tryLock()
Acquires the lock if it is not held by another thread and returns true. And sets lock
hold count to 1.
If current thread already holds lock then method returns true. And increments lock
hold count by 1.
If lock is held by another thread then method return false.

There is no method for lock interruptibility, void lockInterruptibly()


though current thread waits until one of the If current thread already holds lock then method returns true. And increments lock
following thing happens - hold count by 1.
 The lock is acquired by the current If the lock is held by another thread then the current thread waits until one of the
thread, or following thing happens -
 Some other thread interrupts the
 The lock is acquired by the current thread, or
current thread in java.  Some other thread interrupts the current thread.
As soon as current thread acquires the lock it sets lock hold count to 1.

Does not provide any method to return provide int getQueueLength() method to return number of threads that may be
number of threads that may be waiting to waiting to acquire this lock in java.
acquire this lock in java.

holdsLock() method is used to find out whether isHeldByCurrentThread() method is used to find out whether lock is held by
lock is held by current thread or not. If current current thread or not. If current thread holds lock method returns true in java.
thread holds lock method returns true.

Thread can hold lock on object monitor only if current thread already holds lock then lock hold count is increased by 1 when
once. lock() method is called.

method to maintain lock hold count -


void lock()
Acquires the lock if it is not held by another thread. And sets lock hold count to 1.
If current thread already holds lock then lock hold count is increased by 1.
Does not provide any new condition() method. provides newCondition() method.
Method returns a Condition instance to be used with this Lock instance.
Condition instance are similar to using Wait(), notify() and notifyAll() methods on
object.

 IllegalMonitorStateException is thrown if this lock is not held when


any of the Condition waiting or signalling methods are called.

 Lock is released when the condition waiting methods are called and
before they return, the lock is reacquired and the lock hold count restored to what it
was when the method was called in java.

 If a thread is interrupted while waiting then InterruptedException will


be thrown and following things will happen -
o the wait will be over, and
o thread's interrupted status will be cleared.

 Waiting threads are signalled in FIFO (first in first out order) order.
 When lock is fair, first lock is obtained by longest-waiting thread.
If lock is not fair, any waiting thread could get lock, at discretion of
implementation in java.

So, in this thread concurrency tutorial we read what are differences between synchronized and ReEntrantLocks in java

Difference between Externalizable and Serialization interface in java

Now, let's figure out difference between SERIALIZABLE and EXTERNALIZABLE >

SERIALIZABLE EXTERNALIZABLE

Methods It is a marker interface it doesn’t have any It’s not a marker interface.
method. It has method’s called writeExternal() and
readExternal()

Default Serialization YES, Serializable provides its own default NO, we need to override writeExternal() and
process serialization process, we just need to implement readExternal() for serialization process to happen.
Serializable interface.

Customize We can customize default serialization process Serialization process is completely customized
serialization process by defining following methods in our class We need to override Externalizable interface’s
>readObject() and writeObject() writeExternal() and readExternal() methods.
Note: We are not overriding these methods, we
are defining them in our class.

Control over It provides less control over Serialization as it’s Externalizable provides you great control over
Serialization not mandatory to define readObject() and serialization process as it is important to override
writeObject() methods. writeExternal() and readExternal() methods.

Constructor call Constructor is not called during deSerialization. Constructor is called during deSerialization.
during
deSerialization

Significance of using Static and Transient member variables - Static and Transient are not serialized in java

Why static member variables are not part of java serialization process ?
Serialization is applicable on objects or primitive data types only, but static members are class level variables, therefore, different object’s
of same class have same value for static member.
So, serializing static member will consume unnecessary space and time.
Also, if modification is made in static member by any of the object, it won’t be in sync with other serialized object’s value.
What is significance of transient variables?
Serialization is not applicable on transient variables (it helps in saving time and space during Serialization process), we must mark all
rarely used variables as transient. We can initialize transient variables during deSerialization by customizing deSerialization process.

How can you avoid certain member variables of class from getting Serialized?
Mark member variables as static or transient, and those member variables will no more be a part of Serialization.

What is serialVersionUID? Impact of not defining serialVersionUID in class and avoiding InvalidClassException in
java

serialVersionUID is used for version control of object.


If we don’t define serialVersionUID in the class, and any modification is made in class, then we won’t be able to deSerialize our class
because serialVersionUID generated by java compiler for modified class will be different from old serialized object . And
deserialization process will end up throwing java.io.InvalidClassException (because of serialVersionUID mismatch)

The serialization at runtime associates with each serializable class a version number, called a serialVersionUID, which is used during
deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect
to serialization.

We can use eclipse to generate serialVersionUID for our class (as done in below snapshot)

How to avoid warning ‘The serializable class Employee does not declare a static final serialVersionUID field of type long’ ?
Again answer is we can use eclipse to generate serialVersionUID for our class (as mentioned in above screenshot, click on warning button
on left in line 10).

If you have serialized a class & then added few fields in it and then deserialize already serialized version of class, how can you ensure that
you don’t end up throwing InvalidClassException?
>Simply we need to define serialVersionUID in class.

When we Deserialize class ( class which has been modified after Serialization and also class doesn’t declare SerialVersionUID)
InvalidClassException is thrown.
When we Deserialize class ( class which has been modified after Serialization and also class declare SerialVersionUID) its gets
DeSerialized successfully.

Let’s discuss this interesting topic in detail with programs-

First we will serialize a class (class which implements Serialization, but we haven’t declared SerialVersionUID)

Program 1 - to Serialize Object (without serialVersionUID)>

package serDeser4AddSUID;

class Employee implements Serializable {

//we haven’t declared SerialVersionUId


private Integer id;
private String name;

public Employee(Integer id, String name) {


this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + "]";
}
}
public class SerializeEmployee {
public static void main(String[] args) {
Employee object1 = new Employee(1, "amy");
Employee object2 = new Employee(2, "ankit");
try {
OutputStream fout = new FileOutputStream("ser.txt");
ObjectOutput oout = new ObjectOutputStream(fout);
System.out.println("Serialization process has started, serializing employee
objects...");
oout.writeObject(object1);
oout.writeObject(object2);
fout.close();
oout.close();
System.out.println("Object Serialization completed.");

} catch (IOException ioe) {


ioe.printStackTrace();
}
}
}
/*OUTPUT
Serialization process has started, serializing employee objects...
Object Serialization completed.
*/

Then modify class by adding one field in class, but ensure that you don’t run the Serialization process again.

Modify the Serialized class (but don’t serialize the class again)>
class Employee implements Serializable {

private Integer id;


private String name;
private String addedField;
public Employee(Integer id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + "]";
}
}

Now, we have added addedField in class which was already Serialized, let’s see in absence of SerialVersionUID whether we will be able to
DeSerialize our class or not.

Program 2 - to DeSerialize object - program will throw InvalidClassException>

package serDeser4AddSUID;
public class DeSerializeEmployee {

public static void main(String[] args){


try{
InputStream fin=new FileInputStream("ser.txt");
ObjectInput oin=new ObjectInputStream(fin);
System.out.println("DeSerialization process has started, displaying employee objects...");
Employee emp;
while( (emp=(Employee)oin.readObject())!=null ){
System.out.println(emp);
}
fin.close();
oin.close();

}catch(IOException | ClassNotFoundException e){


e.printStackTrace();
}

System.out.println("Object deSerialization completed.");

}
}
/*OUTPUT
DeSerialization process has started, displaying employee objects...
java.io.InvalidClassException: serDeser4AddSUID.Employee; local class incompatible: stream classdesc serialVersionUID =
4822384361417160410, local class serialVersionUID = 5590647880449995492
Object deSerialization completed.
at java.io.ObjectStreamClass.initNonProxy(Unknown Source)
at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
at java.io.ObjectInputStream.readClassDesc(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at serDeser4AddSUID.DeSerializeEmployee.main(DeSerializeEmployee.java:18)
*/
DeSerialization process has ended up throwing InvalidClassException.

Now, let’s see what will happen when we declare serialVersionUID in Serializable class.

Program 3 - to Serialize Object (with serialVersionUID)>

package serDeser4AddSUID;
class Employee implements Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String name;

public Employee(Integer id, String name) {


this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + "]";
}
}
public class SerializeEmployee {
public static void main(String[] args) {
Employee object1 = new Employee(1, "amy");
Employee object2 = new Employee(2, "ankit");
try {
OutputStream fout = new FileOutputStream("ser.txt");
ObjectOutput oout = new ObjectOutputStream(fout);
System.out.println("Serialization process has started, serializing employee
objects...");
oout.writeObject(object1);
oout.writeObject(object2);
fout.close();
oout.close();
System.out.println("Object Serialization completed.");

} catch (IOException ioe) {


ioe.printStackTrace();
}
}
}
/*OUTPUT
Serialization process has started, serializing employee objects...
Object Serialization completed.
*/

Then modify class by adding one field in class, but ensure that you don’t run the Serialization process again.

Modify the Serialized class (but don’t serialize the class again)>

class Employee implements Serializable {

private static final long serialVersionUID = 1L;


private Integer id;
private String name;
private String addedField;
public Employee(Integer id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + "]";
}
}

Now, we have added addedField in class which was already Serialized, let’s see in presence of SerialVersionUID whether we will be able
to DeSerialize our class or not.

Program 4 - to DeSerialize object - Object will be DeSerialized successfully (without InvalidClassException) >

package serDeser4AddSUID;
public class DeSerializeEmployee {

public static void main(String[] args){


try{
InputStream fin=new FileInputStream("ser.txt");
ObjectInput oin=new ObjectInputStream(fin);

System.out.println("DeSerialization process has started, displaying employee objects...");


Employee emp;
while( (emp=(Employee)oin.readObject())!=null ){
System.out.println(emp);
}
fin.close();
oin.close();

}catch(IOException | ClassNotFoundException e){


//e.printStackTrace();
}

System.out.println("Object deSerialization completed.");

}
}
/*OUTPUT
DeSerialization process has started, displaying employee objects...
Employee [id=1, name=amy]
Employee [id=2, name=ankit]
Object deSerialization completed.
*/
DeSerialization process has ended up successfully.

compatible and incompatible changes in Serialization and deSerialization process in java


Compatible Changes :
Compatible changes are those changes which does not affect deSerialization process even if class was updated after being serialized
(provided serialVersionUID has been declared)
 Adding new fields - We can add new member variables in class.
 Adding writeObject()/readObject() methods - We may add these methods to customize serialization process.
 Removing writeObject()/readObject() methods - We may remove these methods and then default customization process will
be used.
 Changing access modifier of a field - The change to access modifiers i.e. public, default, protected, and private have no effect
on the ability of serialization to assign values to the fields.
 Changing a field from static to non static OR changing transient filed to non transient field. - it’s like addition of fields.

InCompatible Changes :
InCompatible changes are those changes which affect deSerialization process if class was updated after being serialized (provided
serialVersionUID has been declared)
 Deletion of fields. (http://stackoverflow.com/questions/16261383/delete-field-from-old-java-class-implementing-
serializable)
 Changing a nonstatic field to static or non transient field to transient field. - it’s equal to deletion of fields.
 Modifying the writeObject() / readObject() method - we must not modify these method, though adding or removing them
completely is compatible change.

If member of class does not implement Serializable interface - than NotSerializableException is thrown in java.

If any of the member does not implement Serializable than NotSerializableException is thrown.

We will use MyClass as a member variable of Serializable class.


Full Program/SourceCode to show that if any of the member does not implement Serializable than NotSerializableException is thrown>

package SerDeser10memberNotSer;
class MyClass {}
class Employee implements Serializable {

private static final long serialVersionUID = 1L;


private Integer id;
private MyClass myClass ;

public Employee(Integer id) {


this.id = id;
myClass=new MyClass();
}
@Override
public String toString() {
return "Employee [id=" + id + "]";
}
}
public class SerializeDeser {
public static void main(String[] args) {
Employee object1 = new Employee(8);
try {
OutputStream fout = new FileOutputStream("ser.txt");
ObjectOutput oout = new ObjectOutputStream(fout);
System.out.println("Serialization process has started, serializing objects...");
oout.writeObject(object1);
System.out.println("Object Serialization completed.");
fout.close();
oout.close();

} catch (IOException e) {
e.printStackTrace();
}
}
}
/*OUTPUT
Serialization process has started, serializing objects...
java.io.NotSerializableException: SerDeser10memberNotSer.MyClass
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
at java.io.ObjectOutputStream.writeSerialData(Unknown Source)
at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
at java.io.ObjectOutputStream.writeObject0(Unknown Source)
at java.io.ObjectOutputStream.writeObject(Unknown Source)
at
SerDeser10memberNotSer.SerializeConstructorCheck.main(SerializeConstructorCheck.java:42)
*/
If we note output, myClass didn’t implemented Serializable interface that’s why Serialization process has thrown NotSerializableException.
How to avoid NotSerializableException?
We got to ensure that during Serialization all the members of class implements Serializable.

Can list, set and maps be Serialized and DeSerialized in java

ArrayList, HashSet and HashMap implements Serializable interface, so if we will use them as member of class they will get Serialized and
DeSerialized as well.

Full Program/SourceCode to show list, set and maps are Serializable and DeSerializable objects>

package serDeser6ListSetMap;
class MyClass implements Serializable {

private static final long serialVersionUID = 1L;


private List<Integer> list;
private Set<Integer> set;
private Map<Integer,Integer> map;

public MyClass(List<Integer> list, Set<Integer> set,


Map<Integer, Integer> map) {
super();
this.list = list;
this.set = set;
this.map = map;
}
@Override
public String toString() {
return "MyClass [list=" + list + ", set=" + set + ", map=" + map + "]";
}

}
public class SerializeEmployee {
public static void main(String[] args) {
List<Integer> list=new ArrayList<Integer>();
list.add(2);
list.add(3);
Set<Integer> set=new HashSet<Integer>();
set.add(4);
set.add(5);
Map<Integer, Integer> map=new HashMap<Integer,Integer>();
map.put(6, 34);
map.put(7, 35);

MyClass object1 = new MyClass(list,set,map);


try {
OutputStream fout = new FileOutputStream("ser.txt");
ObjectOutput oout = new ObjectOutputStream(fout);
System.out.println("Serialization process has started, serializing objects...");
oout.writeObject(object1);
fout.close();
oout.close();
System.out.println("Object Serialization completed.");

//DeSerialization process >

InputStream fin=new FileInputStream("ser.txt");


ObjectInput oin=new ObjectInputStream(fin);
System.out.println("\nDeSerialization process has started, displaying
objects...");
MyClass object=(MyClass)oin.readObject();
System.out.println(object);
fin.close();
oin.close();
System.out.println("Object DeSerialization completed.");

} catch (IOException | ClassNotFoundException e) {


e.printStackTrace();
}
}
}
/*OUTPUT
Serialization process has started, serializing objects...
Object Serialization completed.
DeSerialization process has started, dispalying objects...
MyClass [list=[2, 3], set=[4, 5], map={6=34, 7=35}]
Object DeSerialization completed.
*/

If we note output, we were successfully able to Serialize and DeSerialize list, set and map objects.

Is constructor of class called during DeSerialization process in java

It depends on whether our object has implemented Serializable or Externalizable.

If Serializable has been implemented - constructor is not called during DeSerialization process.
But, if Externalizable has been implemented - constructor is called during DeSerialization process.
Full Program/SourceCode to show that If Serializable has been implemented - constructor is not called during DeSerialization process.

package SerDeser7SerConsCheck;

class Employee implements Serializable {


private static final long serialVersionUID = 1L;
private Integer id;

public Employee(){
System.out.println("No-arg constructor called");
}

public Employee(Integer id) {


System.out.println("1-arg constructor called");
this.id = id;
}
@Override
public String toString() {
return "Employee [id=" + id + "]";
}
}
public class SerializeConstructorCheck {
public static void main(String[] args) {
Employee object1 = new Employee(8);
try {
OutputStream fout = new FileOutputStream("ser.txt");
ObjectOutput oout = new ObjectOutputStream(fout);
System.out.println("Serialization process has started, serializing employee objects...");
oout.writeObject(object1);
fout.close();
oout.close();
System.out.println("Object Serialization completed.");

//DeSerialization process >

InputStream fin=new FileInputStream("ser.txt");


ObjectInput oin=new ObjectInputStream(fin);
System.out.println("\nDeSerialization process has started, displaying employee
objects...");
Employee emp=(Employee)oin.readObject();
System.out.println(emp);
fin.close();
oin.close();
System.out.println("Object DeSerialization completed.");

} catch (IOException | ClassNotFoundException e) {


e.printStackTrace();
}
}
}
/*OUTPUT
1-arg constructor called
Serialization process has started, serializing employee objects...
Object Serialization completed.
DeSerialization process has started, displaying employee objects...
Employee [id=8]
Object DeSerialization completed.
*/
If, we note output, constructor is not called during DeSerialization process.

Full Program/SourceCode to show that if Externalizable has been implemented - constructor is called during DeSerialization process.
>
package SerDeser7ExtConsCheck;
class Employee implements Externalizable {

private static final long serialVersionUID = 1L;


private Integer id;

public Employee(){
System.out.println("No-arg constructor called");
}

public Employee(Integer id) {


System.out.println("1-arg constructor called");
this.id = id;
}
@Override
public String toString() {
return "Employee [id=" + id + "]";
}
/*
* define how Serialization process will write objects.
*/
@Override
public void writeExternal(ObjectOutput oo) throws IOException {
oo.writeInt(id);
}

/*
* define how deSerialization process will read objects.
*/
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
this.id=in.readInt();
}
}
public class ExternalizableConstructorCheck {
public static void main(String[] args) {
Employee object1 = new Employee(8);
try {
OutputStream fout = new FileOutputStream("ser.txt");
ObjectOutput oout = new ObjectOutputStream(fout);
System.out.println("Serialization process has started, serializing employee objects...");
oout.writeObject(object1);
fout.close();
oout.close();
System.out.println("Object Serialization completed.");

//DeSerialization process >

InputStream fin=new FileInputStream("ser.txt");


ObjectInput oin=new ObjectInputStream(fin);
System.out.println("\nDeSerialization process has started, displaying employee
objects...");
Employee emp=(Employee)oin.readObject();
System.out.println(emp);
fin.close();
oin.close();
System.out.println("Object DeSerialization completed.");

} catch (IOException | ClassNotFoundException e) {


e.printStackTrace();
}
}
}
/*OUTPUT
1-arg constructor called
Serialization process has started, serializing employee objects...
Object Serialization completed.
DeSerialization process has started, displaying employee objects...
No-arg constructor called
Employee [id=8]
Object DeSerialization completed.
*/
If, we note output, constructor is called during DeSerialization process.

Is constructor of super class called during DeSerialization process of sub class in java
It is depends on whether our superclass has implemented Serializable or not.

If superclass has implemented Serializable - constructor is not called during DeSerialization process.
If superclass has not implemented Serializable - constructor is called during DeSerialization process.
Full Program/SourceCode to show that If superclass has implemented Serializable - constructor is not called during DeSerialization
process.

package SerDeser9SuperConsCheck;
class Super implements Serializable{
private static final long serialVersionUID = 1L;
public Super(){
System.out.println("No-arg constructor of Super class");
}
}
class Sub extends Super { //it automatically implements Serializable (because it's subclass implements
Serializable).

private static final long serialVersionUID = 1L;


private Integer id;

public Sub(){
System.out.println("No-arg constructor of sub class");
}

public Sub(Integer id) {


System.out.println("1-arg constructor sub class");
this.id = id;
}
@Override
public String toString() {
return "Employee [id=" + id + "]";
}
}
public class SerializeDeser {
public static void main(String[] args) {
Sub object1 = new Sub(8);
try {
OutputStream fout = new FileOutputStream("ser.txt");
ObjectOutput oout = new ObjectOutputStream(fout);
System.out.println("Serialization process has started, serializing objects...");
oout.writeObject(object1);
fout.close();
oout.close();
System.out.println("Object Serialization completed.");

//DeSerialization process >

InputStream fin=new FileInputStream("ser.txt");


ObjectInput oin=new ObjectInputStream(fin);
System.out.println("\nDeSerialization process has started, displaying objects...");
Sub subObj=(Sub)oin.readObject();
System.out.println(subObj);
fin.close();
oin.close();
System.out.println("Object DeSerialization completed.");

} catch (IOException | ClassNotFoundException e) {


e.printStackTrace();
}
}
}
/*OUTPUT
No-arg constructor of Super class
1-arg constructor sub class
Serialization process has started, serializing objects...
Object Serialization completed.
DeSerialization process has started, displaying objects...
Employee [id=8]
Object DeSerialization completed.
*/
If we note output, superclass has implemented Serializable and its constructor is not called during DeSerialization process.

Full Program/SourceCode to show that If superclass has not implemented Serializable - constructor is called during DeSerialization
process.
>
package SerDeser9SuperConsCheck;
class Super {
public Super(){
System.out.println("No-arg constructor of Super class");
}
}
class Sub extends Super implements Serializable{ //it automatically implements Serializable (because it's subclass implements
Serializable).

private static final long serialVersionUID = 1L;


private Integer id;

public Sub(){
System.out.println("No-arg constructor of sub class");
}

public Sub(Integer id) {


System.out.println("1-arg constructor sub class");
this.id = id;
}
@Override
public String toString() {
return "Employee [id=" + id + "]";
}
}
public class SerializeDeser {
public static void main(String[] args) {
Sub object1 = new Sub(8);
try {
OutputStream fout = new FileOutputStream("ser.txt");
ObjectOutput oout = new ObjectOutputStream(fout);
System.out.println("Serialization process has started, serializing objects...");
oout.writeObject(object1);
fout.close();
oout.close();
System.out.println("Object Serialization completed.");

//DeSerialization process >

InputStream fin=new FileInputStream("ser.txt");


ObjectInput oin=new ObjectInputStream(fin);
System.out.println("\nDeSerialization process has started, displaying objects...");
Sub subObj=(Sub)oin.readObject();
System.out.println(subObj);
fin.close();
oin.close();
System.out.println("Object DeSerialization completed.");

} catch (IOException | ClassNotFoundException e) {


e.printStackTrace();
}
}
}
/*OUTPUT
No-arg constructor of Super class
1-arg constructor sub class
Serialization process has started, serializing objects...
Object Serialization completed.
DeSerialization process has started, displaying objects...
No-arg constructor of Super class
Employee [id=8]
Object DeSerialization completed.
*/
If we note output, superclass has not implemented Serializable and its constructor is called during DeSerialization process.

Can subclass avoid Serialization if its superClass has implemented Serialization interface in java

If superClass has implemented Serializable that means subclass is also Serializable (as subclass always inherits all features from its
parent class), for avoiding Serialization in sub-class we can define writeObject() method and throw NotSerializableException() from
there as done below.

private void writeObject(ObjectOutputStream os) throws NotSerializableException


{
throw new NotSerializableException("This class cannot be Serialized");
}

Full Program/SourceCode to show how subclass can avoid Serialization if its superClass has implemented Serialization interface>
package SerDeser11throwNotSerExc;
class Super implements Serializable{
private static final long serialVersionUID = 1L;
}
class Sub extends Super {

private static final long serialVersionUID = 1L;


private Integer id;

public Sub(Integer id) {


this.id = id;
}
@Override
public String toString() {
return "Employee [id=" + id + "]";
}

/*
* define how Serialization process will write objects.
*/
private void writeObject(ObjectOutputStream os) throws NotSerializableException
{
throw new NotSerializableException("This class cannot be Serialized");
}
}
public class SerializeDeserialize {
public static void main(String[] args) {
Sub object1 = new Sub(8);
try {
OutputStream fout = new FileOutputStream("ser.txt");
ObjectOutput oout = new ObjectOutputStream(fout);
System.out.println("Serialization process has started, serializing objects...");
oout.writeObject(object1);
fout.close();
oout.close();
System.out.println("Object Serialization completed.");

} catch (IOException e) {
e.printStackTrace();
}
}
}
/*OUTPUT
Serialization process has started, serializing objects...
java.io.NotSerializableException: This class cannot be Serialized
*/
If we note output, subclass was Serializable (as subclass always inherits all features from its parent class), for avoiding Serialization in
sub-class we defined writeObject() method and throwed NotSerializableException() from there.

Are primitive types part of serialization process in java


Yes, primitive types are part of serialization process. Let’s create a program to prove our point.

Full Program/SourceCode to show that primitive types are also part of Serialization>

package serDeser5PrimitiveTypes;
class Employee implements Serializable {

private static final long serialVersionUID = 1L;


private int id;

public Employee(int id) {


this.id = id;
}
@Override
public String toString() {
return "Employee [id=" + id + "]";
}
}
public class SerializePrimitiveTypes {
public static void main(String[] args) {
Employee object1 = new Employee(8);
try {
OutputStream fout = new FileOutputStream("ser.txt");
ObjectOutput oout = new ObjectOutputStream(fout);
System.out.println("Serialization process has started, serializing employee objects...");
oout.writeObject(object1);
fout.close();
oout.close();
System.out.println("Object Serialization completed.");

//DeSerialization process >

InputStream fin=new FileInputStream("ser.txt");


ObjectInput oin=new ObjectInputStream(fin);
System.out.println("\nDeSerialization process has started, displaying employee
objects...");
Employee emp=(Employee)oin.readObject();
System.out.println(emp);
fin.close();
oin.close();
System.out.println("Object DeSerialization completed.");
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
/*OUTPUT
Serialization process has started, serializing employee objects...
Object Serialization completed.
DeSerialization process has started, displaying employee objects...
Employee [id=8]
Object DeSerialization completed.
*/

If we note output, primitive type int was part of Serialization

package collection.programs;

public class ArrayList_SynchronizationTest


{
public static void main(String[] args) {
List<Integer> list=new ArrayList<Integer>();
List<Integer> synchronizedList = Collections.synchronizedList(list);
System.out.println(Thread.currentThread().getName()+" running");

Thread thread1=new Thread(new Runnable() {


@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" running");
for(int i=0;i<=10;i++)
{
synchronizedList.add(i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
thread1.start();

Thread thread2=new Thread(new Runnable() {


@Override
public void run() {
System.out.println(Thread.currentThread().getName()+" running");
// synchronized (list)
// {
Iterator<Integer> iterator=synchronizedList.iterator();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (iterator.hasNext())
{
System.out.print(iterator.next()+" ");
}
//}
}
});
thread2.start();
}
}

output:-
"C:\Program Files\Java\jdk1.8.0_151\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA Community
Edition 2020.2.2\lib\idea_rt.jar=64861:C:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2020.2.2\bin" -
Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_151\jre\lib\charsets.jar;C:\Program
collection.programs.ArrayList_SynchronizationTest
main running
Thread-0 running
Thread-1 running
Exception in thread "Thread-1" java.util.ConcurrentModificationException

Process finished with exit code 0

* TreeMap is sorted by natural order of keys in java.


In program 3 we used Integer as key, Integer class implements Comparable interface and overrides its compareTo() method.
But, for using Employee as key we it must implement Comparable interface and override its compareTo() method in java.

Note :
RunTimeException) will be thrown. Because, internally TreeMap calls compare method for comparing keys , while
comparing keys casting to java.lang.Comparable will fail at runtime.*/

/*
*TreeMap is sorted by natural order of keys, but we will implement Comparator interface to change the behaviour to sort
TreeMap in descending order of keys.
Comparator interface has been used in form of anonymous inner class in java.
*/

1. What all collection you used in your project ?

I worked on the List Interface, Set Interface, and Map Interface. I used the Implementation of
List as ArrayList and LinkedList. As part of Set Implementation, I have worked on HashSet,
LinkedHashSet and TreeSet. As part of Map Implementation, I worked on HashMap,
LinkedHashMap and TreeMap.
Also, there is few more implementation class like CopyOnWriteArrayList,
CopyOnWriteArraySet and ConcurrentHashMap. Which introduced in
java.util.concurrent.* package.

2. What is the difference between List and Set ?


a. List will allow us to store a duplicate object where Set will not allow to store a
duplicate object.
b. List works on Indexed based where Set works based on the hash value.
c. Always we need to use List when you want to frequently access the elements by using
the index. Where Set is used when you want to design a collection of distinct
elements.
d. So, the moral of using this list and set if u want to allow duplicate object, then go for
list or if you want to maintain a unique object or unique set then u can go for set.

3. What is the difference between ArrayList and LinkedList ?


ArrayList and LinkedList is the 2 implementations of a List Interface.
a) ArrayList Internally uses a dynamic array to store the elements where LinkedList
Internally uses a doubly linked list to store the elements.
b) Manipulation with ArrayList is slow because it internally uses an array. If any
elements is removed from an array all the bits are shifted in memory. Manipulation
with LinkedList is faster than ArrayList because it uses a doubly linked list, so no bit
shifting is required in memory.
c) ArrayList is better for storing and accessing data. LinkedList is better for
manipulating data.

4. List object creation scenario

ArrayList arrayList = new ArrayList<String>();


List<String> list = new ArrayList<>();
What is the difference between these 2 and which one is preferrable to use a list
implementation object.
In case of first scenario here we are directly using an array list implementation which is
tightly coupled but in case of second syntax you can say List is an interface with a reference
of list or with a reference of parent we are creating a object of its implementation class( new
ArrayList()).
In future if I want to create the LinkedList Object then we can simply write new
LinkedList() instead of ArrayList. So, no need to change the complete signature. That’s what
we understand as part of Runtime Polymorphism. With the help of parent reference, we are
creating the object of child. That is what ArrayList is a child and List is an interface.
5. Can’t we use List instead of List<String> ?

It’s always recommended to use the Type Generic that’s why my List will only allow to store
the String Object. So, there will be no Type Cast issue we will face in future if you maintain
the Generic.
6. Declaring a List field with the final keyword ?
Here I declared the list as a final now interviewer will try to understand after declaring List as
a final whether you are able to add the object to this list or not. Even though we declared it as
a final we can modified it there is no immutability. Still, we can modify but we can’t re-
assign this list. With the same reference we can’t create another object. But final doesn’t
mean we can’t modify it.

If you don’t want to modify the List, then you can use
Collections.unmodifiableList(list)

7. How Can I write Custom ArrayList where I don’t want to allow duplicate ?
We know array list will allow duplicate. But I want to create my own ArrayList where I stop allowing the
duplicates.
I have created a class called CustomArrayList we just need to extend it from ArrayList. Then we will use its
own method from the ArrayList method, and we will override the method and we will provide our own logic.
So, I will just override the add() method from the array list.
Now let’s add couple of duplicate values in our customize array list.
So, we can see it doesn’t allow duplicate objects in our list.
So, this is how you can create your own custom array list by extending it from ArrayList or any LinkedList and
you can provide your own implementation to stop allowing duplicates.

8. Why Set doesn’t allow duplicate Element ?


As we know ArrayList will allow duplicate elements, but we can customize, and we can
maintain a non-duplicate object in Array List by creating our own class. But why set doesn’t
allow duplicate let’s see the HashSet implementation…

If you observed the object of add method of HashSet. It will add as a key of a Map. Which
means Set method internally uses a Map. So, add method of HashSet internally uses the map
object to store the value. where we considered the passed argument as a key and Value as a
PRESENT which is nothing but a dummy object value.

So PRESENT is a dummy object. It means Set implementation internally uses a Map to store
object as a key, as we know map key will not allow a duplicate element.
9. Does Set implementation always follow the same rule it does not allow the duplicate
elements ?
No, there is some certain rule if that is not followed by any of the HashSet or any of the Set
implementation or Map implementation then it will allow duplicate object.
Now let me explain that scenario. Let’s assume I have a Student class.
As per rule this Set should not allow duplicate object, right? Bcz s1 and s2 are the same
object it should print only one of them and s3. But we can see all the 3 objects.
Which means Set is not following the rule it allowing duplicates. So, there is a
difference.
If you are using Set with a primitive data type, then its fine no need to override equals() and
hashcode() methods. But if you are using any Custom object or Wrapper Class then you
must need to override equals() and hashCode() methods.
So, let’s override equals() and hashCode() methods.
Now we are getting 2 objects. Which means even though you are using HashSet or HashMap
that’s not guarantee it will not allow duplicate but yes if your custom object is overriding
equals() and hashCode() methods. If they follow the contract of equals() and hashCode()
then always you will get the unique object. There will be no duplicate.
So, This is one of the Interview Question To explain the contract between equals(0 and
hashCode() methods…

10. What is the difference between Comparable and Comparator ?


If we want to sort the collection based on a single element or based on only single fields, we
should go for Comparable but if we want to sort based on multiple parameters with the help
of Comparable, we can’t achieve it we need to go for Comparator.
Comparable affects the original class bcz we are implementing Comparable and overriding
the Comparable method but if we are using Comparator, we were using a separate class.
Let’s create an Employee Class I want to sort based on Id.

If I will use Comparable, then it will directly affect my actual class which is Employee.

Sorting based on Id(integer)


Sorting Based on name(String)

Now in future I got a requirement just change the sorting mechanism based on some other
field now again I need to change this code so in case of comparable its not dynamic its
always like hard coded.
This will recommend if u want to do based on single sorting mechanism.
If I want to sort based on multiple parameters, we should go for Comparator.
//sort based on Id

//sort based on name

11. I just want to sort based on Id if I found Id is same then I will go with the name
sorting ?
So, this comparator basically sort based on Id if it found both the id of its object is same then
it will sort based on the name.

12. Multi Comparing using Comparator Scenario ?


If we sort based on Id if we found Id is same, then sort with name.
13. What is difference between fail-fast and fail-safe Iterator ?
An Iterator which will fail fast when we do any modification while iterating a collection is
called fail-fast iterator. Ex – ArrayList, HashMap and Vector.
Let’s say I have one collection and I was trying to iterating it. While iterating in middle I am
trying to modify something on a same collection object then we will get some exception
which is ConcurrentModificationException. That’s the reason it Is called fail fast iterator.
An Iterator which will allow us to modify in middle while iterating a collection is called fail-
safe iterator. Ex- CopyOnWriteArrayList, CopyOnWriteArraySet and
ConcurrentHashMap. These all are introduced in java.util.concurrent package.
Now one thread is iterating and I am trying to add something in middle I am getting
ConcurrentModificationException the reason here internally this iterator use a modCount
so any changes on the collection will be reflected in the modCount it will change. At the end
it will evaluate the modCount if there is a change found in a modCount. Initially just
assume the modCount size is 0. And here I was adding something then the modCount got
changed to 1. If there is any difference found in modCount then immediately it will throw
the ConcurrentModificationException. So, to prove it let me go to this implementation of
ArrayList.

If u go to modCount initially it assigned to 0.

If u change anything in your collection, then immediately it will increment by 1.

How can we avoid this, so to avoid just use CopyOnWriteArrayList.


So, while iterating we are able to modify the collection that is why it’s called fail-safe or non-
fail fast iterator.
So, now the question is how it work on CopyOnWriteArrayList either it’s going to check
modCount or not.
Yes, it is going to check the mod count but if there is any difference in modCount
immediately it will create a cloned copy of collection and any update will happened to that
cloned copy object instead of this actual collection object.
So, to prove that if u observed here, I used CopyOnArrayList and I add list.add(“c”).
but it will not print because there will be 2 iterations as we have 2 elements a and b so next
while iterating only, we are adding one more element c. so, there will be a next iteration but
in output only we can see 2 iterations.
Which means it’s not adding to this list object. It will add to the copy of list object.so,
internally it will use the copy of list object when there will be any difference in mod count.
Similarly, if I will go to the FailFastMap. .
We are getting exception now what we can do instead of HashMap let us use
ConcurrentHashMap.

But in case of ConcurrentHashMap We are not getting error here bcz it is not using your
cloned copy of Collection implementation. Since we are using Map here so there will be no
copy if u can observe we are getting all the 3 objects. But in case of CopyOnWriteArrayList
we are not getting all values bcz it returns cloned copy of collection bcz when modCount is
getter than expectedModCount it will create a cloned copy of collection instead of throwing
ConcurrentModificationException. But in case of map the implementation is different
there is no cloned copy concepts.
So, you can use ConcurrentHashMap whenever you want to access through parallel
threads or while iterating you want to modify something you can go for
ConcurrentHashMap.

14. What is the need of ConcurrentHashMap and How it is different from HashMap ?

Let’s see one example. I am going to create a class called CustomThread.


Globally I declared one Map object. There is a main thread and another which I extends from
Thread is called a Child thread. Inside child thread I am trying something to add in our map.
Inside main thread I have added 100, 101 and 102. Then I created thread object. From main
thread I am trying to iterate it. But another thread is trying to insert something.

If I run this code, I will get a ConcurrentModificationException.

So, if u observe I will get a ConcurrentModificationException bcz main thread is iterating


the map object and another thread child thread adding something into the same map object at
same time. That’s what we are getting ConcurrentModificationException because we are
using HashMap.
What happened internally this map apply lock on entire object now this map object is
locked so that’s the reason one thread is iterating it got locked and it will not allow other
thread to do something. That’s the reason we are getting ConcurrentModificationException
in case of Map implementation HashMap.
Now instead of HashMap let’s use ConcurrentHashMap.
So, there are no exception, and we are getting all the output.
So, whenever you are using ConcurrentHashMap it allows multiple threads to access
simultaneously. They can able to modify my underlying collection data structure. There will
be no exception.
The reason here in case of ConcurrentHashMap i ConcurrentHashMap doesn’t
allow lock on to the entire map object it apply lock on the Segment level.

So, let’s say you are iterating it now I iterate the first entry since it starts from 0.so its try iterating 100 and A. in
middle thread context switching happened so immediately it will go there and it will add another object. because
we don’t know which thread will execute first parent or child thread. That will be depends on your thread
scheduler. Then child thread will release the lock and main thread will add another entry and what
ConcurrentHashMap does.
It just applies lock on the Segment Level. Rather than applying lock on the entire underlying collection
object. So, HashMap is non synchronized but ConcurrentHashMap is synchronized.
HashMap apply lock on entire object where ConcurrentHashMap applies lock based on the segment. So that is
called segment locking or bucket locking in ConcurrentHashMap.
15. HashMap allows null key or value but ConcurrentHashMap doesn’t allow?

So, in case of key and value is null HashMap not giving any exception. Now if I will change it to the
ConcurrentHashMap I will get the NullPointerException.
Now if I will go to this implementation

But this is not there in HashMap.

16. If we have Hashtable which is already synchronized, then Why we need


ConcurrentHashMap?

Because Hashtable is already synchronized and ConcurrentHashMap is also synchronized


then what is the difference between these 2. Even though Hashtable is synchronized but
Locking mechanism still same as per HashMap it will lock whole underlying data structure.
there will be no segment locking or bucket locking in Hashtable.
If u can see diagram the Hashtable applies lock on entire Hashtable but in
ConcurrentHashMap it applies lock on segment or u can say this is a bucket of a map. So, in
each bucket it will apply the lock not on entire object.
17. We can Synchronize a HashMap using Collections then why can’t we use that
instead using ConcurrentHashMap?
If we used Collections.synchronizedMap(map) it will act as a synchronized Hashtable only
where again locking mechanism is different.
18. How HashMap Internally works?
Let’s say I created one map object. When we create a HashMap object internally it creates a bucket structure
like this since initial capacity of map is 16 initially it creates 16 buckets. Index begin from 0.each bucket
internally uses a linked list. So, in these 16 buckets every bucked is considered as a linked list. This LinkedList
contains one Node. If u observed the internal structure of Node, it contains key, value, hash and next. Which
means each bucket can be considered as a linked list. Each linked list or each bucket can have n number of
nodes.
Let’s create 4 Employee objects to store into a map.

Now when I use map.put(e1, “Dev”) . now how HashMap will identified where I need to keep this entry
between 0 to 15. So, what HashMap internally will do when we call put method. Inside put method there is a
method called hash(key) it will take argument as your key, so my key is nothing Employee 1 object so it will
pass to the hash function it will evaluate some hash value and then based on the modular operator it will identify
the index.
Let’s assume this first entry evaluate index 6 now simply this entry or this node will simply go and
store in bucket 6. My bucket 6 is nothing a linked list and it will store one node. Now I am trying to add 2 nd
object again it will come to the put method and again it will evaluate the hash and then again it evaluates the
index. It evaluates the index as 9. then it will simply go and store in my bucket 9. So, we can see again it store
key, value, hash and next reference null bcz no next node present in that current bucket.

Now let me add 3rd object e3 with some different string. Again, it come to the put method and it evaluate the
hash then it find the index coincidently let’s assume it find the same index which is 6. Now if we will go and
check there is already one element. Now if in a same bucket if you find multiple nodes then that concept is
called Hashing Collison.
So, in that Hashing Collison directly my map will not add this entry to the bucket number which is evaluated by
this index which is 6. So, what it will internally do since both having the same hash value, so it places on the
same bucket immediately map go and check the equals methods e1.equals(e3) to check content wise both are
different or same. If it finds different, then immediately it will store that entry to the same bucket which is
nothing but 6 and now the first entry node next value will not be null it will be the reference of second next node
and the second node next would be the null.
If in a same bucket there is a multiple node, then this condition is called Hashing Collison. So, to avoid the
hashing Collison map internally use == operator to check the reference if both are same reference or different
reference. If it found same reference it will just replace if it found different reference then immediately it will go
and check the content so, the content between the e1 and e3. e1 equal to e3 if it is true then again it will replace
if it found different then it will just add as a next node right to the first node.
Now we have one more element which is e4 let’s assume it found the index 7. Then that node directly goes to
the 7 bucket.

Now interviewer immediately ask you let’s say I pass the key as a null. In map I pass key as a null and a value
as a null then where it will place. Bcz we can’t evaluate the hash and index based on null. If the key is null then
the entry will be added into the 0 bucket.
This is the Internal Implementation of HashMap.
19. What is the enhancement done in HashMap java 8 ?
Initially in this HashMap each Bucket is used as a linked list but in certain threshold it will converted to the
Balance Tree mechanism. That will not be linked list. Let’s say there is a hashing Collison, in the same bucket
they found 5 nodes. Then immediately that linked list will convert to the balance tree and then it will maintain
the balanced between the nodes. Now sure much on Balanced tree internal architecture just go and found on
google.
Initially it will use LinkedList only but after some threshold it will converted to the balanced tree.

20. If key is null in HashMap then where that entry will store in map ?
If the key is null, then the entry will be added into the 0 bucket.
21. Map Enhancement in Java 8 ?
22. How TreeMap internally works?
if you use TreeMap any object will add as a key will preserved the default sorting order then how it is doing the
default sorting order. Let’s see internal implementation.

Now what happened already one entry exist key as a and value as a xyz now whenever you will try to add the
second entry or second object as a key what tree map internally do it will simply check “d”.compareTo(“a”). d
is nothing just a second key compared to the first key which is a. now this compareTo method will always
return integer. now “d”.compareTo(“a”) if it is greater than then it will just as to the right side and it will
return +positive one. If it is less than then it will add to the left side. How it will know that is less than or greater
than based on the return type either +ve or -ve.
So, it will just compare each object or each key if compareTo method return +1 then it will simply add in right
side if it will return -1 then it will simply add in left side. So, this is how it will work.
Let’s see one example …

So, we can see its sorting based on the key.


Here b is greater than a so it placed at right side and d is greater than b so it placed at right side.

You might also like