Tuesday, November 15, 2011

HashMap and Hashtable


Hash table based implementation of the Map interface. This implementation provides all of the optional map operations, and permits null values and the null key. (The HashMap class is roughly equivalent to Hashtable, except that it is unsynchronized and permits nulls.)

This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.

How Hash Map Works:

HashMap works on principle of hashing, we have put () and get () method for storing and retrieving object from Hash Map. When we pass both key and value to put() method to store on HashMap, it uses key object hashcode() method to calculate hash code and then by applying hashing on that hash code 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 hash map stores both key value tuple in every node of linked list.

What will happen if two different HashMap key objects have same hashcode?

They will be stored in same bucket but in the next node of linked list. And keys equals () method will be used to identify correct key value pair in HashMap.

 Difference between HashMap and Hashtable:
  • The HashMap class is roughly equivalent to Hashtable, except that it is non synchronized and permits nulls. (HashMap allows null values as key and value whereas Hashtable doesn't allow nulls).
  • HashMap does not guarantee that the order of the map will remain constant over time.
  • HashMap is non synchronized whereas Hashtable is synchronized.
  • Iterator in the HashMap is  fail-fast  while the enumerator for the Hashtable is not and throw ConcurrentModificationException if any other Thread modifies the map structurally  by adding or removing any element except Iterator's own remove()  method. But this is not aguaranteed behavior and will be done by JVM on best effort.

Hashtable Performance :

To get better performance from your java Hashtable, you need to use the following while instantiating a Hashtable: 
  •  use the initialCapacity and loadFactor arguments
  •  use them wisely
InitialCapacitiy is the number of buckets to be created at the time of Hashtable instantiation. The number of buckets and probability of collision is inversly proportional. If you have more number of buckets than needed then you have lesser possibility for a collision.

For example, if you are going to store 10 elements and if you are going to have initialCapacity as 100 then you will have 100 buckets. You are going to calculate hashCoe() only 10 times with a spectrum of 100 buckets. The possibility of a collision is very very less.

But if you are going to supply initialCapacity for the Hashtable as 10, then the possibility of collision is very large. loadFactor decides when to automatically increase the size of the Hashtable. The default size of initialCapacity is 11 and loadFactor is .75 That if the Hashtable is 3/4 th full then the size of the Hashtable is increased.

New capacity in java Hashtable is calculated as follows:
int newCapacity = oldCapacity * 2 + 1;

If you give a lesser capacity and loadfactor and often it does the rehash() which will cause you performance issues. Therefore for efficient performance for Hashtable in java, give initialCapacity as 25% extra than you need and loadFactor as 0.75 when you instantiate.

ConcurrentHashMap:

It is a hash table supporting full concurrency of retrievals and adjustable expected concurrency for updates. This class obeys the same functional specification a Hashtable, and includes versions of methods corresponding to each method of Hashtable.

However, even though all operations are thread-safe, retrieval operations do not entail locking, and there is not any support for locking the entire table in a way that prevents all access.

Retrieval operations (including get) generally do not block, so may overlap with update operations (including put and remove). Retrievals reflect the results of the most recently completed update operations holding upon their onset.

 For aggregate operations such as putAll and clear, concurrent retrievals may reflect insertion or removal of only some entries. Additionally the iterators and enumerators does not throw ConcurrentModificationException. However iterators are designed to be used by only one thread at a time.

Like Hashtable but unlike HashMap; this class does not allow NULL to be used as either Key or Value.

Difference between Hashtable and ConcurrentHashMap :

Both can be used in multithreaded environment but once the size of hashtable becomes considerable large performance degrade because for iteration it has to be locked for longer duration.

Since ConcurrentHashMap introduced concept of segmentation, how large it becomes only certain part of it gets locked to provide thread safety so many other readers can still access map without waiting for iteration to complete.

In Summary ConcurrentHashMap only locks certain portion of Map while Hashtable locks full map while doing iteration. 



Monday, November 14, 2011

Servlets

A Servlet is a Java class that runs within a web container in an application server, servicing multiple client requests concurrently forwarded through the server and the web container. The web browser establishes a socket connection to the host server in the URL , and sends the HTTP request. Servlets can forward requests to other servers and servlets and can also be used to balance load among several servers.

A browser and a servlet communicate using the HTTP protocol (a stateless request/response based protocol).

A “ServletRequest”, which encapsulates client request from the client and the “ServletResponse”, which encapsulates the communication from the servlet back to the client.

Servlet's Life Cycle :

The Web container is responsible for managing the servlet’s life cycle. The Web container creates an instance of the servlet and then the container calls the init() method. At the completion of the init() method the servlet is in ready state to service requests from clients. The container calls the servlet’s service() method for handling each request by spawning a new thread for each request from the Web container’s thread pool [It is also possible to have a single threaded Servlet, refer Q16 in Enterprise section]. Before destroying the instance the container will call the destroy() method. After destroy() the servlet becomes the potential candidate for garbage collection.




Get and Post Methods :

All client requests are handled through the service() method. The service method dispatches the request to an appropriate method like doGet(), doPost() etc to handle that request.

Below diagram summarizes the differences between Get and Post Methods :


Prefer using doPost() because it is secured and it can send much more information to the server.

If you want a servlet to take the same action for both GET and POST request, you should have doGet call doPost, or vice versa.Below is the code snippet illustration.


ServletConfig:

The ServletConfig parameters are for a particular Servlet.The parameters are specified in the web.xml(i.e. deployment descriptor). It is created after a servlet is instantiated and it is used to pass initialization information to the servlet.


ServletContext:

The ServletContext parameters are specified for the entire Web application. The parameters are specified in the web.xml(i.e.deployment descriptor).Servlet context is common to all Servlets. So all Servlets share information through ServletContext.

Servlet Life Cycle Events:

Servlet lifecycle events work like the Swing events.
  • Any listener interested in observing the ServletContext lifecycle can implement the ServletContextListener interface
  • Listener interested in the ServletContext attribute lifecycle can implement the ServletContextAttributesListener interface.
  • The session listener model is similar to the ServletContext listener model ServletContext’s and Session’s listener objects are notified when servlet contexts and sessions are initialized and destroyed, as well as when attributes are added or removed from a context or session.
The server creates an instance of the listener class to receive events and uses introspection to determine what listener interface (or interfaces) the class implements.

RequestDispatcher:

Defines an object that receives requests from the client and sends them to any resource(such as a servlet, HTML file, or JSP file) on the server.The servlet container creates the RequestDispatcher object, which is used as a wrapper around a server resource located at a particular path or given by a particular name.

This interface is intended to wrap servlets,but a servlet container can create RequestDispatcher
objects to wrap any type of resource.

It uses :
  • Forward - rd.forward(request,response):When it needs to forward the control to another servlet or JSP to generate response.This method allows one servlet to do preliminary processing of a request and another resource to generate the response.
  • Include - rd.include(request, response):When it needs to include the content of the resource such as Servlet, JSP, HTML, Images etc into the calling Servlet’s response.

Following image depicts the difference between Forward or Include and sendRedirect:



Following image depicts the difference between the getRequestDispatcher(String path) method of “ServletRequest” interface and ServletContext interface:


How to make Servlet thread safe:

One approach is to use single threaded model of a servlet by implementing the marker or null interface javax.servlet.SingleThreadedModel.The container will use one of the following approaches to ensure thread safety:
  • Instance pooling where container maintains a pool of servlets.
  • Sequential processing where new requests will wait while the current request is being processed.
Best practice: To use multi-threading and stay away from the single threaded model of the servlet.The single thread model can adversely affect performance.Shared resources can be synchronized, used in read only manner, or shared values can be stored in a session, as hidden fields or in database table.

It is better to avoid instance and static variables

Pre-initialization of a Servlet :

By default the container does not initialize the servlets as soon as it starts up. It initializes a servlet when it receives a request for the first time for that servlet. This is called lazy loading. The servlet deployment descriptor(web.xml) defines the element, which can be configured to make the servlet container load and initialize the servlet as soon as it starts up. The process of loading a servlet before any request comes in is called pre-loading or pre-initializing a servlet. We can also specify the order in which the servlets are initialized.

Servlet clustering :

The clustering promotes high availability and scalability. The considerations for servlet clustering are:
  • Objects stored in a session should be serializable to support in-memory replication of sessions.Also consider the overhead of serializing very large objects. Test the performance to make sure it is acceptable.
  • Design for idempotence. Failure of a request or impatient users clicking again can result in duplicate requests being submitted. So the Servlets should be able to tolerate duplicate requests.
  • Avoid using instance and static variables in read and write mode because different instances may exist on different JVMs. Any state should be held in an external resource such as a database.
  • Avoid storing values in a ServletContext. A ServletContext is not serializable and also the different instances may exist in different JVMs.
  • Avoid using java.io.* because the files may not exist on all backend machines. Instead use getResourceAsStream().

Session Replication :

Session replication is the term that is used when your current service state is being replicated across multiple application instances. Session replication occurs when we replicate the information (i.e. session attributes) that are stored in your HttpSession. The container propagates the changes only when you call the setAttribute(..) method.

Note: Mutating the objects in a session and then by-passing the setAttribute(………..) will not replicate the state change. Example : If you have an ArrayList in the session representing shopping cart objects and if you just call getAttribute(…) to retrieve the ArrayList and then add or change something without calling the setAttribute(…) then the container may not know that you have added or changed something in the ArrayList. So the session will not be replicated.

Constructors in Servlets :

Constructors for dynamically loaded java classes such as Servlets cannot accept arguments.Therefore init() is used to initialize by passing the servletConfig object and other needed parameters.

Also java constructors cannot be declared in an interface and javax.servlet.Servlet is an interface.

However the constructor can be defined in the servlet but the servletConfig object is no accessible in the constructor.