Javarevisited
Javarevisited
Performance
Improving Performance of java application
1. Use bit shift operator for multiplying and divide by 2, computers are very fast with the bitwise
operation.
2. Use StringBuffer in place of the string if you are doing lots of string manipulation it will reduce
memory by avoiding creating lots of string garbage. If you are using java5 then consider StringBuilder
but that is not synchronized.
3. try to make variable , class , method final whenever possible that allows compiler to do lots of
optimization e.g. compile time binding so you will get faster output.
4. static methods are bonded compile time while non-static methods are resolved at runtime based
on object type so the static method will be faster than non-static.
5. don't call methods in for loop for checking condition e.g. length() size() etc.
for(int i=0; i<vector.size();i++)
J2SE
Core
Object
equals() method is used to compare Objects for equality while hashCode is used to generate an
integer code corresponding to that object. equals and hashCode have used extensively in Java core
library like they are used while inserting and retrieving Object in HashMap, equals method is also
used to avoid duplicates on HashSet and other Set implementation and every other place where you
need to compare Objects.
1) If two objects are equal by equals() method then there hashcode must be same.
2) If two objects are not equal by equals() method then there hashcode could be same or
different.
So this was the basic theory about equals method in Java now we are going to discuss the approach
on how to override equals() method, yes I know you all know this stuff :) but I have seen some
of equals() code which can be improved by following correct approach. For illustration purpose we
will see an example of Person class and discuss How to write equals() method in Java for that class.
Here is my approach for overriding equals method in Java. This is based on standard approach most
of Java programmer follows while writing equals method in Java.
3) Do the instanceof check, if instanceof return false than return false from equals in Java , after
some research I found that instead of instanceof we can use getClass() method for type
identification because instanceof check returns true for subclass also, so its not strictly equals
comparison until required by business logic. But instanceof check is fine if your class
is immutable and no one is going to sub class it. For example we can replace instanceof check by
below code
4) Type cast the object; note the sequence instanceof check must be prior to casting object.
6) Compare individual attribute starting with numeric attribute because comparing numeric
attribute is fast and use short circuit operator for combining checks. If first field does not
match, don't try to match rest of attribute and return false. It’s also worth to remember
doing null check on individual attribute before calling equals() method on them recursively
to avoidNullPointerException during equals check in Java.
/**
* Person class with equals and hashcode implementation in Java
* @author Javin Paul
*/
public class Person {
private int id;
private String firstName;
private String lastName;
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj == null || obj.getClass() != this.getClass()) {
return false;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((firstName == null) ? 0 : firstName.hashCode());
result = prime * result + id;
result = prime * result
+ ((lastName == null) ? 0 : lastName.hashCode());
return result;
}
If you look above method we are first checking for "this" check which is fastest available check for
equals method then we are verifying whether object is null or not and object is of same type or not.
only after verifying type of object we are casting it into desired object to avoid
any ClassCastException in Java. Also while comparing individual attribute we are comparing numeric
attribute first using short circuit operator to avoid further calculation if its already unequal and doing
null check on member attribute to avoid NullPointerException.
2) Second mistake I have seen while overriding equals() method is not doing null check for member
variables which ultimately results in NullPointerException in Java during equals() invocation. For
example in above code correct way of calling equals() method of member variable is after doing null
check as shown below:
3) Third common mistake is not overriding hashCode method in Java and only
overriding equals() method. You must have to override both equals() and hashCode() method in Java
, otherwise your value object will not be able to use as key object in HashMap because working
of HashMap is based on equals() and hashCode to read more see , How HashMap works in Java.
4) Last common mistake programmer make while overriding equals() in Java is not
keeping equals() and compareTo() method consistent which is a non formal requirement in order to
obey contract of Set to avoid duplicates. SortedSet implementation like TreeSet uses compareTo to
compare two objects like String and if compareTo() and equals() will not be consistent than TreeSet
will allow duplicates which will break Set contract of not having duplicates. To learn more about this
issue see my post Things to remember while overriding compareTo in Java
testReflexive() this method will test reflexive nature of equals() method in Java.
testSymmeteric() this method will verify symmetric nature of equals() in Java.
testNull() this method will verify null comparison and will pass if equals method
returns false.
testConsistent() should verify consistent nature of equals method in Java.
testNotEquals() should verify if two object which are not supposed to equals is actually not
equal, having negative test cases in test suite is mandatory.
testHashCode() will verify that if two objects are equal by equals() method in Java then there
hashcode must be same. This is an important test if you are thinking to use this object as key
in HashMap or Hashtable
1) Most of the IDE like NetBeans, Eclipse and IntelliJ IDEA provides support to
generate equals() and hashcode() method. In Eclipse do the right click-> source ->
generate hashCode() and equals().
2) If your domain class has any unique business key then just comparing that field in equals method
would be enough instead of comparing all the fields e.g. in case of our example if "id" is unique for
every Person and by just comparing id we can identify whether two Person are equal or not.
3) While overriding hashCode in Java makes sure you use all fields which have been used in equals
method in Java.
4) String and Wrapper classes like Integer, Float and Double override equals method
but StringBuffer doesn’t override it.
5) Whenever possible try to make your fields immutable by using final variables in Java, equals
method based on immutable fields are much secure than on mutable fields.
6) Don't use instanceof check in equals method, as it could break contract of equals() method in sub-
class, results in non-symmetric equals, because instanceof return true for child class as well. For
example, if you compare two objects Parent and Child from same type-
hierarchy; Parent.equals(child) will return true, because child instanceof Parent is true,
but Child.equals(parent) will return false, because Parent instanceof Child is false. This
means equals() is not following symmetric contract, which states if a.equals(b) ==
true than b.equals(a) == true, as shown below :
public class Parent {
}
Output :
child instanceof Parent true
parent instanceof Child false
Alternatively, you can mark equals as final method to prevent it from being overridden.
8) Use IDE or Apache commons EqualsBuilder and HashCodeBuilder utility classes to automatically
implement equals() and hashcode() method in Java.
9) Two object which is logically equal but loaded from different ClassLoader cannot be equals.
Remember that getClass() check, it will return false if class loader is different.
10) Use @Override annotation on hashcode() as well, as it also prevents subtle mistakes over return
type. e.g. return type of hashcode() method is int, but many times programmers mistakenly put long.
12) From Java 7 you can also use a new utility class called java.util.Objects for null safe equality
check and calculating hash code. You can replace our null-safe code for check equality :
to much concise
Objects.equals(name, guest.getName());
Another worth noting point is that Hibernate only guarantees equivalence of database row
(persistent identity) and Java object inside a particular Session. Which means if you store instances
retrieved in different Sessions in a Set, you will be having duplicates. Now the most important aspect
of overriding equals and hashcode() for hibernate entity classes, you should never decide equality
just based upon identifier. Though it’s convenient to compare identifier to see if the belong to same
database row, Unfortunately, we can't use this approach with generated identifiers.
Since Hibernate only assign identifier values to the object that are persistent, a newly created
instance will not have any identifier value. Similarly, if an instance is not persisted, and currently in
a Set, saving it to database will assigned an identifier value, which will further change the value
of hashcode() method, finally results in breaking the contract of the Set. That's why it's best to
implement equals and hashcode in Hibernate using business key equality e.g. an Employee is same if
it's name, surname, father's name, department, date of birth is same. Properties which are not
prone to change e.g. date of birth are better candidate of business equality than those which is
easier to change e.g. address and contact number.
In short, remember these best practices while overriding equals() and hashcode() for Hibernate
entity class :
1) Don't let your equals() method only uses identifier values for equivalence check.
2) Implement equals() and hashCode() using real word key that would identify instance in real world.
4) Don't use getClass() to compare object equality because Hibernate uses proxy and this check will
always fail. Instead use instanceof operator, it respect proxy because they have IS-A relationship
with actual object.
5) Use getter and setter methods to access properties instead of directly accessing the, because
hibernate lazily initialize object, when there getProperty() method is called. Using name may return
null but getName() may return value from database.
Runtime API
Though it’s not recommended but some time it’s become necessary to execute native operating
system or shell command from JAVA, especially if you are doing some kind of reporting or
monitoring stuff and required information can easily be found using native command. This is not
advised though because then you will lose platform independence which is why we mostly used
JAVA.
Anyway if you no choice and you want to execute native commands from JAVA then it’s good to
know that how we can do it, many of you probably know this but for those who don't know and
have never done it we will see through an example.
Suppose you want to execute "ls" command in Linux which list down all the files and directory in a
folder and you want to do it using JAVA.
In JAVA we have a class called "java.lang.Runtime" which is used to interact with Runtime system has
facility to execute any shell command using method exec().
Here is the code sample which can be used to execute any native command from JAVA.
try {
// Run ls command
Process process = Runtime.getRuntime().exec(cmd);
} catch (Exception e) {
e.printStackTrace(System.err);
}
This is little nice tip which can be very handy in some specific situation but in by and large its not
advised by the very own reason of making JAVA code platform dependence.
as pointed out by Jaroslav sedlacek If not done properly it can easily hang the application. Java and
external process communicate through buffers. If buffer fills up, the external process stops and waits
until java empties the buffer. Java app has to read both output and error streams of the process to
prevent this blocking. There is good util class ProcessBuilder since 1.5 in java or apache commons
exec can be used too.
Classpath
Classpath in Java is the path to directory or list of the directory which is used by ClassLoaders to find
and load class in Java program.
Classpath can be specified using CLASSPATH environment variable which is case insensitive, -cp or -
classpath command line option or Class-Path attribute in manifest.mf file inside JAR file in Java.
Also don't confuse Classpath with PATH in Java, which is another environment variable used to find
java binaries located in JDK installation directory, also known as JAVA_HOME.
The main difference between PATH and CLASSPATH is that former is used to locate Java commands
while later is used to locate Java class files.
In fact, CLASSPATH is an environment variable which is used by JVM to locate user defined classes.
Setting Java Classpath in Windows
In order to set Classpath for Java in Windows (any version Windows XP, Windows 2000 or Windows
7) you need to specify the value of environment variable CLASSPATH, the name of this variable is not
case sensitive and it doesn’t matter if the name of your environment variable is Classpath,
CLASSPATH or classpath in Java.
you can also set classpath in windows by using DOS command like:
set CLASSPATH=%CLASSPATH%;JAVA_HOME\lib;
This way you can set the classpath in Windows XP, windows 2000 or Windows 7 and 8, as they all
come with command prompt.
By default, Java CLASSPATH points to current directory denoted by "." and it will look for any class
only in the current directory.
I have used this feature of Java Classpath to test my patch releases, we used to have a folder called
"patch" listed as first element in Java CLASSPATH and any point of time we want to put any debug
statement or want to test any bug we just modify Java source file, compile it and generate class file
and put that inside patch folder instead of creating JAR file and releasing whole new Java
application. This is very handy if you are working on a large project where you don't have
development environment setup in Windows and your project only runs on Unix server. This
approach is much faster than remote debugging Java application in Eclipse
It's also worth noting that when you use the java -jar command line option to run your Java program
as an executable JAR, then the CLASSPATH environment variable will be ignored, and also the -cp
and -classpath switches will be ignored. In this case, you can set your Java classpath in the META-
INF/MANIFEST.MF file by using the Class-Pathattribute. In short Class-path attribute in manifest file
overrides classpath specified by -cp, -classpath or CLASSPATH environment variable.
Now a common question if I have my CLASSPATH variable pointing to current directory "." and I have
a class called "Test" inside package "testing" and with below directory structure C:\project\testing\
Test.class in my computer.
What will happen if I run the command "java Test" from directory "C:\project\testing\"? will it
run?
No, it will not run it will give you:
Exception in thread "main" java.lang.NoClassDefFoundError: Test
Since the name of the class is not Test, instead it’s testing.Test even though your classpath is set to
current directory.
Now what will happen if I give command java testing.Test from C:\project\testing\ it will again not
run and give an error?
Why because now it looking for class called Test which is in package testing, starting from current
directory "." but don't find it since there is no directory called "testing after this path "C:\project\
testing\".
To run it successfully you need to go back to directory C:\project and now run
C:\project>java testing.Test and It will run successfully because of Classpath issues I prefer to use
Eclipse rather than running Java program from command prompt.
ClassNotFoundException is an Exception and will be thrown when Java program dynamically tries to
load a Java class at Runtime and don’t find the corresponding class file on the classpath. Two
keywords here “dynamically” and “runtime”. A classic example of these errors is whey you try to
load JDBC driver by using Class.forname(“driver name”) and greeted
with java.lang.ClassNotFoundException: com.mysql.jdbc.Driver. So this error essentially comes when
Java try to load a class using forName() or by loadClass() method of ClassLoader. The key thing to
note is that presence of that class on Java classpath is not checked on compile time. So even if those
classes are not present on Java classpath your program will compile successfully and only fail when
you try to run.
2. You can override the value of Classpath in Java defined by environment variable
CLASSPATH by providing JVM command line option –cp or –classpath while running your
application.
3. If two classes with the same name exist in Java Classpath then the class which comes
earlier in Classpath will be picked by Java Virtual Machine.
4. By default CLASSPATH in Java points to current directory denoted by "." and it will look
for any class only in the current directory.
5. When you use the -jar command line option to run your program as an executable JAR,
then the Java CLASSPATH environment variable will be ignored, and also the -cp and -
classpath switches will be ignored and, In this case, you can set your java classpath in
the META-INF/MANIFEST.MF file by using the Class-Path attribute.
6. In Unix of Linux, Java Classpath contains names of the directory with colon “:” separated,
On Windows Java Classpath will be semicolon “;” separated while if you defined java
classpath in Manifest file those will be space separated.
7. You can check value of classpath in java inside your application by looking at following
system property “java.class.path” System.getProperty("java.class.path")
Class-Path attribute is used to contain classpath inside manifest file. Also, make sure that
your manifest file must end with a blank line (carriage return or new line), here is an
example of java classpath in the manifest file.
Main-Class: com.classpathexample.Demo_Classpath
Class-Path: lib/tibco.jar lib/log4j.jar
8. It’s also important to note that path specified in the manifest file is not
absolute instead they are relative from application jar’s path. For example, in above if
your application jar file is in C:\test directory you must need a lib directory inside test and
tibco.jar and log4j.jar inside that.
9. ClassNotFoundException is an Exception and will be thrown when Java program
dynamically tries to load a particular Class at Runtime and don’t find that on Java classpath
due to result of Class.forName() or loadClass() method invocation.
10. NoClassDefFoundError comes when a particular class was present in Java Classpath during
compile time but not available during runtime on Classpath in Java.
OOP
Abstraction in Java. Abstract Class or Interface
Abstraction is a way to segregate implementation from an interface and one of the five
fundamentals along with Encapsulation, Inheritance, Polymorphism, Class and Object.
Abstraction in Java is achieved by using interface and abstract class in Java. An interface or abstract
class is something which is not concrete, something which is incomplete. In order to use interface or
abstract class, we need to extend and implement an abstract method with concrete behaviour.
One example of Abstraction is creating interface to denote common behaviour without specifying
any details about how that behaviour works e.g. You create an interface called Server which has
the start() and stop() method. This is called abstraction of Server because every server should have a
way to start and stop and details may differ.
An abstract class is something which is incomplete and you cannot create an instance of the abstract
class. If you want to use it you need to make it complete or concrete by extending it. A class is called
concrete if it does not contain any abstract method and implements all abstract method inherited
from abstract class or interface it has implemented or extended. By the way Java has a concept of
abstract classes, abstract method but a variable cannot be abstract in Java.
A popular example of abstract class in Java is ActionListener which has an abstract method
called actionPerformed(ActionEvent ae). This method is called when an ActionEvent is fired like
when you click on JButton. It's common in java to attach ActionListener with JButton by
implementing abstract method actionPerformed(ActionEvent ae) using Anonymous class, as shown
in below Example :
An abstract method in Java doesn't have the body, it's just a declaration. In order to use an
abstract method, you need to override that method in sub class.
When you know something needs to be there but not sure how exactly it should look like. e.g.
when I am creating a class called Vehicle, I know there should be methods like start() and stop() but
don't know how that start and stop method should work, because every vehicle can have different
start and stop mechanism e.g. some can be started by kicking or some can be by pressing buttons .
The Same concept applies to interface in Java as well, which we will discuss in some other post.
So the implementation of those start() and stop() methods should be left to their concrete
implementation e.g. Scooter, MotorBike , Car etc.
let’s see one example : how about representing a classroom using OOPS?
A classroom is a room, which has certain no of chairs, desks, blackboard, teacher, students etc.
Now in order to represent that in code, we need to write a program. In Java we will write like this.
//members
int noOfChairs;
int noOfDesks;
Teacher currentTeacher;
Students [] students;
Blackboard blackboard;
//methods
public int getNoOfChairs(){ }
I have omitted most of the methods, just to focus on concept rather than implementation. So now
we know that class is blueprint, which has member variable and methods and used to create object.
Now what is object here, any classroom in which any lecture is going on , your first lecture would be
one instance, second lecture would be another instance.
See the point, every object of same class has same no of variables but there value gets changed e.g.
lecture 1 was attended by 15 students by teacher called Mr. Gupta , lecture 2 was attended by 18
students which was by Miss Amrita.
Anything which you see around can be represented in class and object e.g. this blog is an instance of
Blog class, a particular movie can be instance of Movie class e.g. Titanic is an instance of Movie
where actor/director are different than other movie.
Class
java.lang.Class is one of the most important class in java and it provides several utility methods
e.g. getClass(), forName() which is used to find and load a class, you might have used to load Oracle
or MySQL drivers. It also provides methods like Class.newInstance() which is the backbone of
reflection and allow you to create an instance of a class without using new() operator.
The class has no public constructor and its instance is created by JVM when a class is loaded. The
object of class Class is also used to represent classes, enum, interfaces and annotation in a running
Java application. The primitive types e.g. byte, short, char, int, float, double and boolean are also
represented by Class instances.
You can get the corresponding Class instance by using class literals e.g. int.class, float.class or
boolean.class. It is also used to represent an instance of the array in Java. Every array with the same
type and same dimension share the same instance of class Class.
Another use of java.lang.Class is while implementing equals() method to check whether two objects
are of the same type or not.
Every time JVM creates an object, it also creates a java.lang.Class object that describes the type of
the object. All instances of the same class share the same Class object and you can obtain the Class
object by calling the getClass() method of the object. By the way, this method is inherited
from java.lang.Object class.
if(A.getClass() == B.getClass()){
System.out.println("A and B are instances of same class");
}else{
System.out.println("A and B are instances of different class");
}
In this case, it will print "A and B are instances of the same class" because they are both instance of
class Person.
We need forName() and newInstance() because many times it happens that we don’t know the
name of the class to instantiate while writing code , we may get it from config files, database,
network or from any upstream Java or C++ application.
This is what we called the reflective way of creating an object which is one of the most powerful
feature of Java and which makes way for many frameworks e.g. Spring ,Struts which uses Java
reflection.
Wrapper Classes
Java 5 introduced auto-boxing which automatically converts int to Integer and because of that many
Java developers started writing code for comparing int variable to Integer object and Integer to
Integer using == operator. You should avoid that because it can create subtle bugs in your program
because it only works for a particular range of integers and not for all.
There is another problem as well when you compare int variable to Integer object using == operator,
the Integer object is converted to a primitive value. This can throw null pointer exception if the
Integer object is null.
Now when you compare two Integer object using a == operator, Java doesn't compare them by
value, but it does reference comparison. When means even if the two integer has the same value, ==
can return false because they are two different objects in the heap.
Caching of integer objects by Integer.valueOf() method. What this mean is that your program will
work for some input but not for others. This happens because auto boxing
uses Integer.valueOf() method to convert Integer to int and since this method caches Integer object
for range -128 to 127, it return same Integer object in heap, and that's why == operator return true if
you compare two Integer object in the range -128 to 127, but return false afterwards, causing bug.
Before Java 1.4 that was not a problem because there was no autoboxing, so you always knew that
== will check reference in heap instead of value comparison.
Integer i1 = 260;
Integer i2 = 260;
if (i1 == i2) {
System.out.println("i1 and i2 is equal");
} else {
System.out.println("i1 and i2 is not equal ");
}
Here you will most probably get "i1 and i2 is not equal " at least in my machine.
Because in this case, unboxing operation is not involved. The literal 260 is boxed into two different
Integer objects (again it varies between JVM to JVM) , and then those objects are compared with ==.
The result is false, as the two objects are different instances, with different memory addresses.
Because both sides of the == expression contain objects, no unboxing occurs.
i1 = -128;
i2 = -128;
if (i1 == i2) {
System.out.println("i1 and i2 is equal");
} else {
System.out.println("i1 and i2 is not equal ");
}
i1 = 127;
i2 = new Integer(127);
if (i1 == i2) {
System.out.println("i1 and i2 is equal");
} else {
System.out.println("i1 and i2 is not equal");
}
Here, most probably you will get the text "i1 and i2 is equal".
Because int values from -128 to 127 are in a range which most JVM will like to cache so the VM
actually uses the same object instance (and therefore memory address) for both i1 and i2. As a
result, == returns a true result. For 2nd snippet, it returns "i1 and i2 is not equal"
This is very indeterministic and only shown by example since some JVM do optimization at certain
integer value and try to return same object every time but it’s not guaranteed or written behaviour.
So best is to avoid this kind of code in post Java 1.5 and instead use equals() method to compare
Integers in Java, which is more deterministic and correct.
String
Immutability, Caching, hashcode calculation(HashMap), Security are the most important reason.
1) The string is Immutable in Java because String objects are cached in String pool. Since cached
String literals are shared between multiple clients there is always a risk, where one client's action
would affect all another client. For example, if one client changes the value of String "Test" to
"TEST", all other clients will also see that value. Caching of String objects was important from
performance reason; this risk was avoided by making String class Immutable.
Imagine String pool facility without making string immutable , it’s not possible at all because in case
of string pool one string object/literal e.g. "Test" has referenced by many reference variables, so if
any one of them change the value others will be automatically gets affected i.e. let’s say
2) String has been widely used as parameter for many Java classes e.g. for opening network
connection, you can pass hostname and port number as string, you can pass database URL as a string
for opening database connection, you can open any file in Java by passing the name of the file as
argument to File I/O classes.
In case, if String is not immutable, this would lead serious security threat, I mean someone can
access to any file for which he has authorization, and then can change the file name either
deliberately or accidentally and gain access to that file. Because of immutability, you don't need to
worry about that kind of threats. This reason also gels with, Why String is final in Java, by
making java.lang.String final, and Java designer ensured that no one overrides any behaviour of
String class.
3) Since String is immutable it can safely share between many threads which are very important for
multithreaded programming and to avoid any synchronization issues in Java, Immutability also
makes String instance thread-safe in Java, means you don't need to synchronize String operation
externally. Another important point to note about String is the memory leak caused by SubString,
which is not a thread related issues but something to be aware of.
4) It allows HashMap to cache its hashcode and do not calculate every time we call hashcode
method of String, which makes it very fast as HashMap key to be used in HashMap in Java. In short
because String is immutable, no one can change its contents once created which guarantees
hashcode of String to be same on multiple invocations.
Since HashMap works in the principle of hashing, which requires same has value to function
properly. Mutable String would produce two different hashcode at the time of insertion and retrieval
if a content of String was modified after insertion, potentially losing the value object in the map.
5) The most important reason that String is immutable is that it is used by the class loading
mechanism, and thus have profound and fundamental security aspects. Had String been mutable, a
request to load "java.io.Writer" could have been changed to load "mil.vogoon.DiskErasingWriter"
Security and String pool being primary reason of making String immutable.
Threading
Actually public void run() method is defined in Runnable interface and since java.lang.Thread class
implements Runnable interface it gets this method automatically.
which way of implementing Thread is better? Extending Thread class or implementing Runnable
method?
In my opinion implementing Runnable is better because in Java we can only extend one class so if we
extend Thread class we cannot extend any other class while by implementing Runnable interface we
still have that option open with us.
Second reason which make sense to me is more on OOPS concept according to OOPS if we extend a
class we provide some new feature or functionality, So if the purpose is just to use the run() method
to define code its better to use Runnable interface. If you are still not convince on why implementing
Runnable is better than extending Thread class for creating threads in Java
You have implemented thread by now. Next step is to actually create object of thread class and start
it. This is will create a separate path of execution parallel to main thread.
Java thread is state based so it remains in predefined state at any given time and state transition
occurs by calling different thread method. So, when you create object of your class which has
implemented Runnable or extended Thread, you just create an object of Thread class, Thread will
not start until you call the start() method of java.lang.Thread class.
This is shown clearly in above thread state transition diagram in Java. It is now in NEW state, when
we call start() method Java Virtual machine execute run() method of that Thread class it goes into
RUNNBLE state.
Now, it's upto thread scheduler to assign CPU to this thread. From here on it can either complete its
execution and go to TERMINATED state or can go into WAITING, TIMED WAITING and BLOCKED
state. By the way if you notice, when we call start() method, it eventually calls run() method.
what will happen if we call the run() method directly instead of calling start() method ?
run() method will simply be executed in the same Thread and new Thread will not be created.
What will happen if you call start() method twice in same Thread object?
mythread.start();
mythread.start(); //this line will throw IllegalThreadStateException
Bonus Tip
TIP1: It’s not guaranteed that thread mythread will start before thread myrunnable it depends upon
Thread scheduler.
TIP2: Thread will be said to go on dead state once execution of run() method finished and you can
not start that thread again.
Lock
What is deadlock?"
When two or more threads are waiting for each other to release lock and get stuck for infinite time,
situation is called deadlock . It will only happen in case of multitasking.
How do you detect deadlock in Java ?
I would look at the code if I see nested synchronized block or calling one synchronized method from
other or trying to get lock on different object then there is good chance of deadlock if developer is
not very careful.
Other way is to find it when you actually get locked while running the application, try to take thread
dump , in Linux you can do this by command "kill -3" , this will print status of all the thread in
application log file and you can see which thread is locked on which object.
Other way is to use jconsole, it will show you exactly which threads are get locked and on which
object.
/*
* * This method also requests same two lock but in exactly * Opposite order
* i.e. first Integer and then String. * This creates potential deadlock, if
* one thread holds String lock * and other holds Integer lock and they wait
* for each other, forever.
*/
public void method2() {
synchronized (Integer.class) {
System.out.println("Aquired lock on Integer.class object");
synchronized (String.class) {
System.out.println("Aquired lock on String.class object");
}
}
}
If method1() and method2() both will be called by two or many threads , there is a good chance of
deadlock because if thread 1 acquires lock on Sting object while executing method1() and thread 2
acquires lock on Integer object while executing method2() both will be waiting for each other to
release lock on Integer and String to proceed further which will never happen.
This diagram exactly demonstrate our program, where one thread holds lock on one object and
waiting for other object lock which is held by other thread.
How to avoid deadlock in Java?
If you have looked above code carefully then you may have figured out that real reason for deadlock
is not multiple threads but the way they are requesting lock, if you provide an ordered access then
problem will be resolved, here is my fixed version, which avoids deadlock by avoiding circular wait
with no pre-emption
/*
* * This method also requests same two lock but in exactly * Opposite order
* i.e. first String and then Integer.
*/
public void method2() {
synchronized (String.class) {
System.out.println("Aquired lock on String.class object");
synchronized (Integer.class) {
System.out.println("Aquired lock on Integer.class object");
}
}
}
Now there would not be any deadlock because both methods are accessing lock
on Integer and String class literal in same order. So, if thread A acquires lock on Integer object ,
thread B will not proceed until thread A releases Integer lock, same way thread A will not be blocked
even if thread B holds String lock because now thread B will not expect thread A to release Integer
lock to proceed further.
e.g. find out whether thread NewsReader has a lock on NewsPaper object or not?.
I managed to provide the logic based upon the properties of synchronized block and wait() and
notify() method, as shown in the first answer but he wasn't satisfied at that time.
1) I thought about IllegalMonitorStateException which wait() and notify() methods throw when they
get called from non-synchronized context so I said I would call newspaper.wait() and if this
call throws an exception it means thread is not holding the lock, otherwise thread holds the lock.
2) Later I discovered that thread is a static method called holdsLock(Object obj) which returns true
or false based on whether threads holds a lock on the object passed.
Collection
Map
HashMap in Java works on hashing principle. It is a data structure which allows us to store object
and retrieve it in constant time O(1) provided we know the key.
In hashing, hash functions are used to link key and value in HashMap. Objects are stored by
calling put(key, value) method of HashMap and retrieved by calling get(key) method. When we call
put method, hashcode() method of the key object is called so that hash function of the map can find
a bucket location to store value object, which is actually an index of the internal array, known as the
table.
HashMap internally stores mapping in the form of Map.Entry object which contains both key and
value object.
When you want to retrieve the object, you call the get() method and again pass the key object. This
time again key object generate same hash code (it's mandatory for it to do so to retrieve the object
and that's why HashMap keys are immutable e.g. String) and we end up at same bucket location. If
there is only one object then it is returned and that's your value object which you have stored
earlier. Things get little tricky when collisions occur.
Since the internal array of HashMap is of fixed size, and if you keep storing objects, at some point of
time hash function will return same bucket location for two different keys, this is called collision in
HashMap. In this case, a linked list is formed at that bucket location and a new entry is stored as next
node.
If we try to retrieve an object from this linked list, we need an extra check to search correct value,
this is done by equals() method. Since each node contains an entry, HashMap keeps comparing
entry's key object with the passed key using equals() and when it return true, Map returns the
corresponding value.
Since searching inlined list is O(n) operation, in worst case hash collision reduce a map to linked list.
This issue is recently addressed in Java 8 by replacing linked list to the tree to search in O(logN) time.
Do you Know how HashMap works in Java or How does get () method of HashMap works in Java
HashMap works on the principle of hashing, we have put(key, value) and get(key) method for
storing and retrieving Objects from HashMap. When we pass Key and Value object to put() method
on Java HashMap, HashMap implementation calls hashCode method on Key object and applies
returned hashcode into its own hashing function to find a bucket location for storing Entry object,
important point to mention is that HashMap in Java stores both key and value object as Map.Entry in
a bucket which is essential to understand the retrieving logic.
What will happen if two different objects have the same hashcode?
two unequal objects in Java can have same hashcode. Since HashMap uses LinkedList to store object,
this entry (object of Map.Entry comprise key and value) will be stored in LinkedList. Great this
answer make sense though there are many collision resolution methods available like linear
probing and chaining, this is simplest and HashMap in Java does follow this. But story does not end
here and interviewer asks
How will you retrieve Value object if two Keys will have the same hashcode?
Interviewee will say we will call get() method and then HashMap uses Key Object's hashcode to find
out bucket location and retrieves Value object but then you need to remind him that there are two
Value objects are stored in same bucket, we will call keys.equals() method to identify a correct node
in LinkedList and return associated value object for that key in Java HashMap. Perfect this is the
correct answer.
Some good developer point out here that using immutable, final object with
proper equals() and hashcode() implementation would act as perfect Java HashMap keys
and improve the performance of Java HashMap by reducing collision. Immutability also allows
caching their hashcode of different keys which makes overall retrieval process very fast and suggest
that String and various wrapper classes e.g. Integer very good keys in Java HashMap.
Now if you clear this entire Java HashMap interview, You will be surprised by this very interesting
question "What happens On HashMap in Java if the size of the HashMap exceeds a given
threshold defined by load factor ?". Until you know how HashMap works exactly you won't be able
to answer this question. If the size of the Map exceeds a given threshold defined by load-factor e.g.
if the load factor is .75 it will act to re-size the map once it filled 75%. Similar to other collection
classes like ArrayList, Java HashMap re-size itself by creating a new bucket array of size twice of the
previous size of HashMap and then start putting every old element into that new bucket array. This
process is called rehashing because it also applies the hash function to find new bucket location.
If you manage to answer this question on HashMap in Java you will be greeted by "do you see any
problem with resizing of HashMap in Java" , you might not be able to pick the context and then he
will try to give you hint about multiple thread accessing the Java HashMap and potentially looking
for race condition on HashMap in Java.
So the answer is Yes there is potential race condition exists while resizing HashMap in Java, if
two thread at the same time found that now HashMap needs resizing and they both try to resizing.
on the process of resizing of HashMap in Java, the element in the bucket which is stored in linked list
get reversed in order during their migration to new bucket because Java HashMap doesn't append
the new element at tail instead it append new element at the head to avoid tail traversing. If race
condition happens then you will end up with an infinite loop. Though this point, you can potentially
argue that what the hell makes you think to use HashMap in multi-threaded environment to
interviewer :)
Some more Hashtable and HashMap Questions
Few more question on HashMap in Java which is contributed by readers of Javarevisited blog:
1) Why String, Integer and other wrapper classes are considered good keys?
String, Integer and other wrapper classes are natural candidates of HashMap key, and String is most
frequently used key as well because String is immutable and final, and
overrides equals and hashcode() method. Other wrapper class also shares similar property.
Immutability is required, in order to prevent changes on fields used to calculate hashCode() because
if key object returns different hashCode during insertion and retrieval than it won't be possible to
get an object from HashMap.
Immutability is best as it offers other advantages as well like thread-safety, If you can keep your
hashCode same by only making certain fields final, then you go for that as well.
Since equals() and hashCode() method is used during retrieval of value object from HashMap, it's
important that key object correctly override these methods and follow contact. If unequal object
returns different hashcode than chances of collision will be less which subsequently improve the
performance of HashMap.
Just to summarize here are the answers which do make sense for above questions
HashMap works on the principle of hashing, we have put() and get() method for storing and
retrieving object from HashMap.When we pass both key and value to put() method to store on
HashMap, it uses key object hashcode() method to calculate hashcode and them by applying hashing
on that hashcode it identifies bucket location for storing value object. While retrieving it uses key
object equals method to find out correct key value pair and return value object associated with that
key. HashMap uses linked list in case of collision and object will be stored in next node of linked
list. Also, HashMap stores both key and value tuple in every node of linked list in the form of
Map.Entry object.
What will happen if two different HashMap key objects have the same hashcode?
They will be stored in the same bucket but no next node of linked list. And keys equals () method will
be used to identify correct key value pair in HashMap.
How null key is handled in HashMap? Since equals() and hashCode() are used to store and retrieve
values, how does it work in case of the null key?
The null key is handled specially in HashMap, there are two separate methods for
that putForNullKey(V value) and getForNullKey(). Later is offloaded version of get() to look up null
keys. Null keys always map to index 0. This null case is split out into separate methods for the sake
of performance in the two most commonly used operations (get and put), but incorporated with
conditionals in others. In short, equals() and hashcode() method are not used in case of null keys in
HashMap.
private V getForNullKey() {
if (size == 0) {
return null;
}
for (Entry<K,V> e = table[0]; e != null; e = e.next) {
if (e.key == null)
return e.value;
}
return null;
}
In terms of usage, Java HashMap is very versatile and I have mostly used HashMap as cache in an
electronic trading application I have worked. Since finance domain used Java heavily and due to
performance reason we need caching HashMap and ConcurrentHashMap comes as very handy
there. You can also check following articles from Javarevisited to learn more about HashMap and
Hashtable in Java:
We all know that HashMap is a data structure which is used to store key and value pairs of object in
java. It is dynamic and can add values without specifying size of map. This article will try to explain
working of hashmap in java in aspect of its dynamic size and hashing.
Working of HashMap in Java is depending on multiple aspects. This article will deal with how it can
grow in size store hashes. There are certain factors to consider in understanding working of
HashMap in Java.Let us understand them a bit
Initial Capacity: This is the capacity of hashmap to store number of key value pairs when it
is instantiated.
Load Factor: A parameter responsible to determine when to increase size of hashmap
Size : number of key value pairs in hashmap.
Threshold value: When number of key value pairs is more than threshold value, then
hashmap is resized.
Now, if you see the HashMap source code in java, you’ll see that initial capacity is 16 by default and
the load factor is 0.75. Based on these parameters, threshold value is calculated where threshold
value is the product of load factor and size. So threshold value is 12 for a newly created instance of
HashMap. Let us try something out.
When new HashMap() is instantiated, load factor is initialized to 0.75 and initial capacity is 16.
Threshold is still 0.
When first key is put in hashmap, then threshold value is calculated which will be product of
initial capacity and load factor i.e. 16 * 0.75 = 12.
Now as the for loop keeps on adding key value pairs in HashMap, as soon as number of key value
pairs, i.e. size of hashmap exceeds threshold value, HashMap is rehashed and capacity becomes
approximately twice the previous size. Let us see what happens to each parameter in the table
below.
0 0 16 0
1 1 16 12
2 2 16 12
3 3 16 12
4 4 16 12
5 5 16 12
6 6 16 12
7 7 16 12
8 8 16 12
9 9 16 12
10 10 16 12
11 11 16 12
12 12 16 12
13 13 32 24
14 14 32 24
Please note that capacity of hashmap became twice as soon as size of hashmap exceeded the
threshold value. So this will go one continuously. If size becomes 25 then capacity becomes 64 and
threshold becomes 48. This keeps going on.
Working of HashMap Put Method
Before going into depth of hashmap put method, please read what are hashcodes and significance of
equals and hashcode methods.
After reading above articles, you’ve known now for user defined objects, we must override equals
and hashcode methods for objects to become good hashing keys. Let us consider we have
a Bike class and we are making below assumptions.
Now, we know that HashMaps use buckets i.e. hashcode and some objects are placed into it which
have same hashcode. How does it work internally? Let us try to understand it.
@Override
public String toString() {
return "Bike [manufacturer=" + manufacturer + ", enginecapacity=" + enginecapacity
+ "]";
}
Note that for simplicity, for hashCode, we are simply returning the engineCapacity of Bike so that all
bikes with same engineCapacity will fall into same bucket. i.e. they will have same hashcode.
bikes.put(cbr250r, null);
bikes.put(fireblade, null);
bikes.put(ninja250r, null);
}
}
When bikes.put(cbr250r, null); is invoked, a table of type Entry is created with initial capacity
= 16 as mentioned in previous article. So an array of Entry elements is created with its index
from 0 to 15.
The hash value of cbr250r is calculated based on which the index of array of type Entry is
decided. Let us say index value is 10.
Now a new node is created which holds the key as cbr250r, if the bucket is currently not
referring to any node, it will refer to this newly created node. The structure of HashMap will
be something like below
So at the end of bikes.put(cbr250r, null); operation, a node is created with cbr250r object which is
being referred by 10th element in the array of Entry objects.
Now, when we add fireblade using bikes.put(fireblade, null); very similar operations will occur and it
will be another entry in the array as its hashcode will be different. So HashMap will look like below
after adding fireblade.
fireblade added
Now comes the tricky part. We are going to perform bikes.put(ninja250r, null); , this is what happens
under the hood.
hash value for ninja250r is calculated based on our hashCode() implementation, which is
250.
Now, the index for corresponding hash is determined.
As cbr250r has the same hashcode, the index in array of Entry objects will be the same
for ninja250r also.In our case, the index is 10
Now it is checked whether the array element at index 10 i.e. table[10] is already referring to
some linked list or not. If yes, the list is traversed till the end and newly put object is added
to end of the linked list.
So ninja250r will be added at the end of list referred by table[10].
I hope this article helped understand the working of hashmap put method. In next article, we will
learn how get method works while finding the objects.
bikes.get(ninja250r);
Here is how HashMap get method works in this case. HashMap will be able to find the object only if
there is an object in HashMap which will have same hashCode and all fields are equal.
HashMap vs Hashtable
Though both Hashtable and HashMap are data-structure based upon hashing and implementation of
Map interface, the main difference between them is that.
1. HashMap allows one null key and null values but Hashtable doesn't allow null key or values.
Also, thread-safety of the hash table is achieved using internal synchronization, which makes
it slower than HashMap.
2. HashMap is not thread-safe but Hashtable is thread-safe. Which means you cannot use
HashMap in multi-threaded Java application without external synchronization
4. One more notable difference between Hashtable and HashMap is that because of thread-
safety and synchronization Hashtable is much slower than HashMap if used in Single
threaded environment. So if you don't need synchronization and HashMap are only used by
one thread, it outperforms Hashtable in Java.
5. HashMap does not guarantee that the order of the map will remain constant over time.
2) Fail-safe is relevant from the context of iterators. If an Iterator or ListIterator has been created on
a collection object and some other thread tries to modify the collection object "structurally", a
concurrent modification exception will be thrown. It is possible for other threads though to invoke
"set" method since it doesn't modify the collection "structurally". However, if prior to calling "set",
the collection has been modified structurally, "IllegalArgumentException" will be thrown.
3) Structurally modification means deleting or inserting element which could effectively change the
structure of the map.
Iterator
Enumeration is also a legacy class since JDK1.0 and not all Collection supports it e.g. Vector supports
Enumeration but ArrayList doesn't. While iterator was introduced later and can be used with
ArrayList, HashSet and other collection classes.
Only major difference between Enumeration and iterator is Iterator has a remove() method while
Enumeration doesn't. Enumeration acts as Read-only interface, because it has the methods only to
traverse and fetch the objects, whereas by using Iterator we can manipulate the objects like adding
and removing the objects from collection e.g. Arraylist.
Also Iterator is more secure and safe as compared to Enumeration because it does not allow other
thread to modify the collection object while some thread is iterating over it and
throws ConcurrentModificationException.
Enumeration Iterator
hasMoreElement hasNext
nextElement next
N/A remove
FIX Protocol
Before setup of VPN, some contracts needs to be sorted out by both party.
e.g.
1) Encryption key
2) Protocol used
3) VPN Connector IP
once your VPN connection got setup, you can connect to your brokers trading system on there
respective IP/Port.
What is an Exchange?
Exchange – An exchange is a highly organized market where (especially) tradeble securities,
commodities, foreign exchange, futures and options contracts are sold and bought. Exchange brings
together brokers and dealers who buy and sell these objects.
Examples of exchanges are Bombay Stock Exchange, NeyWork Stock Exchange (NYSE), Tokyo Stock
Exchange (TSE)
What is the difference between Sell Orders and Short Sell Orders?
Sell means selling your own securities , short selling means selling securities without owning them
normally broker lend securities to user.there are
two kinds of short sell e.g. Covered Short Sell and naked Short Sell, most of the stock exchanges
doesn't allow naked short sell because its normally abused to take stock price downward.
FIX (financial information exchange) protocol is the global protocol used for Electronic trading of
different asset classes e.g Equity, Fixed Income FX (foreign exchange) , Derivatives Futures and
Options and its knowledge is essential to understand Electronic trading and FIX messages. I have
listed some of the very common but informative questions asked in fix protocol interview question,
this list is by no means complete and only contains questions on top of my mind, I would encourage
reader to post any question they have been asked and I will include on this list, Please feel free to
ask any other question related to FIX (financial information exchange) protocol I would be happy to
answer those. FIX messaging is a term used to describe communication using FIX protocol.
If you are Java developer looking for FIX + Java jobs then having a look on these FIX (financial
information exchange) protocol interview snippets can benefit you in an interview. usually for an FIX
(financial information exchange) protocol job interviewer test whether the candidate has actually
worked in FIX protocol or not and whether he is familiar with various FIX tags and different FIX
protocol version or not.
Since FIX (financial information exchange) versions differ significantly from one version to another
knowledge of FIX tags and their value for a particular version is very important. There are lots of jobs
available for Core Java and FIX (financial information exchange) protocol developer even if you had
worked in FIX for 1 year you could be very much sought after in job market.
What are differences between FIX 4.0 and FIX 4.2? (answer)
In FIX 4.0 we had a tag called ExecTranType which describes Execution type in FIX 4.2 this tag is
merged with ExecType (tag 150) and now OrdStatus will show the status of order instead of
Execution type. Later versions of FIX (financial information exchange) protocol is now 5.0 or even
higher.
Hikenari (Market order on close) = this order type can be placed either for the closing of morning
session or closing of the afternoon session. However, if an order is placed for the closing of the
morning session and there are still unexecuted quantities, then the remaining quantity (not expired
at morning close) is treated as a market order for "the opening of afternoon session".
If an order is placed during afternoon session, it is treated as a market order on afternoon close
Sashinari and Hikenari are available in TOCOM exchange.
Only the first few fields of the header must be in sequence, see FIX (financial information exchange)
Spec Volume 1. "The first three fields in the standard header are BeginString (tag #8) followed by
BodyLength (tag #9) followed by MsgType (tag #35)."
Also "General message format is composed of the standard header followed by the body followed by
the standard trailer."
Fields of the header thus must not appear in the body, if they then FIX engine will not be able to
parse and understand the message and will complain about it.
So if a Trader has any view on Market he can take advantage of that while working with BI order.
What is the difference between Application level Reject (MsgType=8 and ExecType=8) and Session
level reject (MsgType=3)?
FixEngine will reject any message which doesn't confirm FIX protocol i.e. some mandatory tags
missing e.g. MsgType with Session level reject , application will not get that message for processing ,
while application e.g. OMS or Execution System will reject message based on Business logic or FIX
(financial information exchange) Protocol trade life cycle with application level Reject (MsgType=8
and ExecType=8).
So whenever a new client comes on board a new Fix Session will be needed for him who will be identified by host, port and comp ids e.g.
SenderCompID and TargetCompID. Before you setup a new financial information exchange (FIX) session in your fix engine you will need to
require network connectivity between client's network and your network, this usually done by network team and for security reasons
some firewall rules also needs to be setup. While working on this part you may face several network connectivity issue based on what are
you choosing e.g. Radianz, VPN or internet.
Once network connection gets established you are ready to connect to client. Now client will send logon request (MessagType=A) with
sequence no 1, 1 (At start of day) and with SenderCompID and TargetCompID agreed upon. On TCP layer first of all socket connection
gets established in client IP and your IP and your Fix Engine listens on port specified. once your Fix Engine gets logon request its validate
content and authenticity of client and if all is OK it replies with another logon request message. Now your financial information exchange
(FIX) session is established and you are ready to send orders via this connection.
Some important points to remember while troubleshooting FINANCIAL INFORMATION EXCHANGE (FIX) connectivity issues:
1) Which FINANCIAL INFORMATION EXCHANGE (FIX) Protocol versions are you using for
connectivity? Both counterparties must use same version of FINANCIAL INFORMATION
EXCHANGE (FIX) Protocol to establish FIX Connectivity.
2) Are you sending Correct SenderCompID (FIX Tag 49) and TargetCompID (FIX tag 50)?
CompIDs must be configured on FIX Acceptor side.
3) Are you using correct IP and Port?
4) Are yor FIX Engine is sending correct sequence number which brokers FIX Engine is
expecting?
5) Are you handling Resend request correctly?
Design Pattern
Which classes are candidates of Singleton? Which kind of class do you make Singleton in Java?
Any class which you want to be available to whole application and whole only one instance is viable
is candidate of becoming Singleton. One example of this is Runtime class, since on whole java
application only one runtime environment can be possible making Runtime Singleton is right
decision.
Another example is a utility classes like Popup in GUI application, if you want to show popup with
message you can have one PopUp class on whole GUI application and anytime just get its instance,
and call show() with message.
Can you write code for getInstance() method of a Singleton class in Java?
I have seen many programmer write Singleton getInstance() method with double checked locking
but they are not really familiar with the caveat associated with double checking of singleton prior to
Java 5.
Answer : Until asked don’t write code using double checked locking as it is more complex and
chances of errors are more but if you have deep knowledge of double checked locking, volatile
variable and lazy loading than this is your chance to shine.
Is it better to make whole getInstance() method synchronized or just critical section is enough?
Since locking only make sense when we need to create instance and rest of the time it’s just read
only access so locking of critical section is always better option.
Answer : This is again related to double checked locking pattern, well synchronization is costly and
when you apply this on whole method than call to getInstance() will be synchronized and contented.
Since synchronization is only needed during initialization on singleton instance, to prevent creating
another instance of Singleton, It’s better to only synchronize critical section and not whole method.
What is lazy and early loading of Singleton and how will you implement it?
As there are many ways to implement Singleton like using double checked locking or Singleton class
with static final instance initialized during class loading. Former is called lazy loading because
Singleton instance is created only when client calls getInstance() method while later is called early
loading because Singleton instance is created when class is loaded into memory.
if(_INSTANCE == null){
synchronized(Singleton.class){
//double checked locking - because second check of Singleton instance with lock
if(_INSTANCE == null){
_INSTANCE = new Singleton();
}
}
}
return _INSTANCE;
}
Double checked locking should only be used when you have requirement for lazy initialization
otherwise use Enum to implement singleton or simple static final variable.
How do you prevent for creating another instance of Singleton using clone() method?
Preferred way is not to implement Cloneable interface as why should one wants to create clone() of
Singleton and if you do just throw Exception from clone() method as “Can not create clone of
Singleton class”.
How do you prevent for creating another instance of Singleton using reflection?
Since constructor of Singleton class is supposed to be private it prevents creating instance of
Singleton from outside but Reflection can access private fields and methods, which opens a threat of
another instance. This can be avoided by throwing Exception from constructor as “Singleton already
initialized”
How do you prevent for creating another instance of Singleton during serialization?
You can prevent this by using readResolve() method, since during serialization readObject() is used
to create instance and it return new instance every time but by using readResolve you can replace it
with original Singleton instance. I have shared code on how to do it in my post Enum as Singleton in
Java. This is also one of the reason I have said that use Enum to create Singleton because
serialization of enum is taken care by JVM and it provides guaranteed of that.
Why you should avoid the singleton anti-pattern at all and replace it with DI?
Singleton Dependency Injection: every class that needs access to a singleton gets the object through
its constructors or with a DI-container.
Why Singleton is Anti pattern
With more and more classes calling getInstance() the code gets more and more tightly coupled,
monolithic, not testable and hard to change and hard to reuse because of not configurable, hidden
dependencies. Also, there would be no need for this clumsy double checked locking if you
call getInstance less often (i.e. once).
At last few more questions for your practice, contributed by Mansi, Thank you Mansi
Singletons often control access to resources such as database connections or sockets. For example, if
you have a license for only one connection for your database or your JDBC driver has trouble with
multithreading, the Singleton makes sure that only one connection is made or that only one thread
can access the connection at a time. If you add database connections or use a JDBC driver that
allows multithreading, the Singleton can be easily adjusted to allow more connections.
Moreover, Singletons can be stateful; in this case, their role is to serve as a unique repository of
state. If you are implementing a counter that needs to give out sequential and unique numbers (such
as the machine that gives out numbers in the deli), the counter needs to be globally unique. The
Singleton can hold the number and synchronize access; if later you want to hold counters in a
database for persistence, you can change the private implementation of the Singleton without
changing the interface.
On the other hand, Singletons can also be stateless, providing utility functions that need no more
information than their parameters. In that case, there is no need to instantiate multiple objects that
have no reason for their existence, and so a Singleton is appropriate.
The Singleton should not be seen as way to implement global variables in the Java programming
language; rather, along the lines of the factory design patterns, the Singleton lets you encapsulate
and control the creation process by making sure that certain prerequisites are fulfilled or by creating
the object lazily on demand.
However, in certain situations, two or more Singletons can mysteriously materialize, disrupting the
very guarantees that the Singleton is meant to provide. For example, if your Singleton Frame is
meant as a global user interface for your application and two are created, your application will have
two Frames on the screen -- quite confusing for the user. Further, if two counters are created where
one was intended, then clients requesting numbers will not get the desired sequence 1, 2, 3... but
rather a multiple sequence such as 1, 1, 2, 2, 3, 3, 3.... Additionally, if several instances of a database-
connection Singleton are created, you might start receiving SQLExceptions complaining about "too
many database connections."
In this article, I'll describe those phenomena and how to avoid them. After discussing how to
implement the Singleton, I'll go over the sometimes surprising causes for the phenomena one by
one, showing you how they occur and how you can avoid making those mistakes. I hope that in the
process you will learn about classloading, multithreading, distributed systems, Design Patterns, and
other interesting topics, as I did.
Implementing Singletons
There are a few ways to implement Singletons. Although you can get Singleton-like behavior with
static fields and methods [for example, java.lang.Math.sin(double)], you gain more flexibility by
creating an instance. With Singletons implemented as single instances instead of static class
members, you can initialize the Singleton lazily, creating it only when it is first used. Likewise, with a
Singleton implemented as single instance, you leave open the possibility of altering the class to
create more instances in the future. With some implementations of the Singleton, you allow writers
of subclasses to override methods polymorphically, something not possible with static methods.
Most commonly, you implement a Singleton in Java by having a single instance of the class as a static
field. You can create that instance at class-loading time by assigning a newly created object to the
static field in the field declaration, as seen in Listing 1.
Listing 1
public class MySingleton {
private static MySingleton _instance = new MySingleton();
private MySingleton() {}
Alternatively, you can instantiate it lazily, on first demand, as seen in Listing 2. You keep the
constructor private to prevent instantiation by outside callers.
Listing 2
public class MySingleton {
private static MySingleton _instance;
private MySingleton() {
// construct object . . .
}
Both Singleton implementations do not allow convenient subclassing, since getInstance(), being
static, cannot be overridden polymorphically. Other implementations prove more flexible. While I
don't have the space to describe alternative implementations in detail, here are a couple of
possibilities:
If you implement a factory class with a method that returns the Singleton instance, you
allow yourself flexibility in the runtime class of the return value, which can be
either MySingleton or a subclass thereof. You may have to make the constructor nonprivate
to make that work.
You can have a SingletonFactory class with a globally accessible map of class names
or Class objects to Singleton instances. Again, the runtime type of the instances can be
either the type indicated by the class name or a subclass, and the constructor will not be
private.
Now that we've looked briefly at implementation, let's turn to the heart of this article: how two
Singletons can exist simultaneously.
For example, only the EJB container decides how and when to create EJB objects or to recycle
existing ones. The EJB may exist in a different VM from the code that calls it. Moreover, a single EJB
can be instantiated simultaneously in several VMs. For a stateless session bean, multiple calls to
what appears, to your code, to be one instance could actually be calls to different instances on
different VMs. Even an entity EJB can be saved through a persistence mechanism between calls, so
that you have no idea what instance answers your method calls. (The primary key that is part of the
entity bean spec is needed precisely because referential identity is of no use in identifying the bean.)
The EJB containers' ability to spread the identity of a single EJB instance across multiple VMs causes
confusion if you try to write a Singleton in the context of an EJB. The instance fields of the Singleton
will not be globally unique. Because several VMs are involved for what appears to be the same
object, several Singleton objects might be brought into existence.
Systems based on distributed technologies such as EJB, RMI, and Jini should avoid Singletons that
hold state. Singletons that do not hold state but simply control access to resources are also not
appropriate for EJBs, since resource management is the role of the EJB container. However, in other
distributed systems, Singleton objects that control resources may be used on the understanding that
they are not unique in the distributed system, just in the particular VM.
Multiple class loaders occur more commonly than you might think. When browsers load classes from
the network for use by applets, they use a separate class loader for each server address. Similarly,
Jini and RMI systems may use a separate class loader for the different code bases from which they
download class files. If your own system uses custom class loaders, all the same issues may arise.
If loaded by different class loaders, two classes with the same name, even the same package name,
are treated as distinct -- even if, in fact, they are byte-for-byte the same class. The different class
loaders represent different namespaces that distinguish classes (even though the classes' names are
the same), so that the two MySingleton classes are in fact distinct. Since two Singleton objects
belong to two classes of the same name, it will appear at first glance that there are two Singleton
objects of the same class.
This problems exists in older Java Virtual Machines1. JDK 1.2 VMs, in particular, conform to a newer
class garbage collection model that forbids any class in a given classloader to be collected until all
are unreferenced Programming Java threads in the real world, Part 7 in Resources). You can avoid
class garbage collection in the older VMs by holding a reference to the Singleton class or object in
some other object that persists for the program's life. You can also set your VM to have no class
garbage collection (-Xnoclassgc on the JRE 1.3, or -noclassgc on the IBM JVM). Keep in mind that if
you have a long-running program that frequently reloads classes (perhaps through special class
loaders such as the remote class loaders), you have to consider whether that could cause a
problematic buildup of garbage classes in the VM.
Purposely Reloaded Singleton Classes
Classes are reloaded not only after class garbage-collection; they can also be reloaded at Java
programs' request. The servlet specifications allow servlet engines to do that at any time. When the
servlet engine decides to unload a servlet class, it calls destroy(), then discards the servlet class;
later, the servlet engine can reload the servlet class, instantiate the servlet object, and initialize it by
calling init(). In practice, the process of unloading and reloading may occur in a servlet engine when
a servlet class or JSP changes.
Like the previous two cases, the present case involves newly loaded classes. Here, however, classes
are ditched on purpose, while a new copy of the class loads.
Depending on the servlet engine, when an old servlet class is discarded, the associated classes might
not be, even if they have changed. So if a servlet gets a reference to a Singleton object, you may find
that there is one Singleton object associated with the old servlet class and one associated with the
new.
As servlet engines differ in their class-reloading policies, the Singleton behavior is unpredictable
unless you understand how your servlet engine's class-loading mechanisms work.
Similar problems can occur if you hold a reference from another object to a servlet and some chain
of references keeps that object from the garbage collector. Then, when the servlet class should be
discarded, it cannot be, and you may find the servlet class loaded twice in the VM.
Listing 3
// error, no synchronization on method
public static MySingleton getInstance() {
if (_instance==null) {
_instance = new MySingleton();
}
return _instance;
}
Two Singletons will be created if the constructor runs and simultaneously another thread calls the
method. Thread-safe code is particularly important in Singletons, since that Design Pattern is meant
to give the user a single point of access that hides the complexities of the implementation, including
multithreading issues.
Multiple instances can be created even if you add a synchronized(this) block to the constructor call,
as in Listing 4:
Listing 4
// Also an error, synchronization does not prevent
// two calls of constructor.
public static MySingleton getInstance() {
if (_instance==null) {
synchronized (MySingleton.class) {
_instance = new MySingleton();
}
}
return _instance;
}
In the correct solution, seen in Listing 5, make getInstance() a synchronized method:
Listing 5
// correct solution
public static synchronized MySingleton getInstance() {
// . . . continue as in Listing 3
Double-checked locking is another common solution but, unfortunately, it does not work (see Listing
6).
Listing 6
// Double-checked locking -- don't use
public static MySingleton getInstance() {
if (_instance==null) {
synchronized (MySingleton.class) {
if (_instance==null) {
_instance = new MySingleton();
}
}
}
}
In this situation, we intend to avoid the expense of grabbing the lock of the Singleton class every
time the method is called. The lock is grabbed only if the Singleton instance does not exist, and then
the existence of the instance is checked again in case another thread passed the first check an
instant before the current thread.
Unfortunately, double-checked locking causes problems. To wit, compiler optimizations can make
the assignment of the new Singleton object before all its fields are initialized. The only practical
solution is to synchronize the getInstance() method (as in Listing 2).
The uniqueness of the class cannot be imposed as a compile-time constraint on the subclass unless
you use a private constructor. If you want to allow subclassing, for example, you might make the
constructor protected. A subclass could then expose a public constructor, allowing anyone to make
instances. Since an instance of a subclass is an instance of your superclass, you could find multiple
instances of the Singleton.
Multiple Singletons Created by a Factory Specially Asked to Create Multiple Objects
One of the strengths of the Singleton design pattern, as opposed to static methods, is that if you
change your mind and want more than one, the Singleton class can be easily altered.
For example, most servlets run as Singletons in their servlet engines. Since that can cause threading
problems, in one alternative (not recommended, but available) the servlet can
implement SingleThreadModel. In that case, the servlet engine may, if necessary, create more than
one servlet instance. If you are used to the more common Singleton servlets, you may forget that
some servlets can occur in multiple instances.
If you accidentally have more than one factory object for one of the reasons above, you will still have
two of the created objects, even if each factory object is built correctly.
I assume you already know what a singleton is and why it's an anti-pattern. If not, I recommend you
read this StackOverflow thread: What is so bad about singletons?
Now that we agree it's a bad deal, what do we do if we need to, let's say, have access to a database
connection pool in many different places within the application? We simply need something like this:
class Database {
public static Database INSTANCE = new Database();
private Database() {
// create a connection pool
}
public java.sql.Connection connect() {
// Get new connection from the pool
// and return
}
}
Later in at, say, the JAX-RS REST method, we need to retrieve something from the database:
@Path("/")
class Index {
@GET
public String text() {
java.sql.Connection connection =
Database.INSTANCE.connect();
return new JdbcSession(connection)
.sql("SELECT text FROM table")
.fetch(new SingleOutcome(String.class))
}
}
In case you're not familiar with JAX-RS, it's a simple MVC architecture, and this text() method is a
"controller." Additionally, I'm using JdbcSession, a simple JDBC wrapper from jcabi-jdbc.
Forget about singletons; never use them; turn them into dependencies
We need to make this database connection pool dependency of the controller and ensure it's
provided through a constructor. However, in this particular case, for JAX-RS, we can't do it through a
constructor thanks to its ugly architecture. But we can create a ServletContextListener, instantiate
a Database in its contextInitialized() method, and add that instance as an attribute of servletContext.
Then, inside the controller, we retrieve the servlet context by adding
the javax.ws.rs.core.Context annotation to a setter and using getAttribute() on it. This is absolutely
terrible and procedural, but it's better than a singleton.
A proper object-oriented design would pass an instance of Database to all objects that may need it
through their constructors.