hidden and output comments

hidden: <%-- --%> output:

implicit objects

request, response, pageContext, session, application, out, config, page, exception

64 kb limit

JVM has a 64kb limit on the size of the method and the entire JSP page is rendered as a single method. If a JSP page is greater than 64kb, this probably indicates poor implementation. When this method reaches its limit of 64kb it throws an error. This error can be overcome by splitting the JSP files and including them dynamically (i.e. using ) because the dynamic includes generate separate JSP Servlet for each included file.

static vs dynamic include

  • Static include: <%@ include %>, During the translation or compilation phase all the included JSP pages are compiled into a single Servlet.
  • Dynamic include: , The dynamically included JSP is compiled into a separate Servlet. It is a separate resource, which gets to process the request, and the content generated by this resource is included in the JSP response. Has run time performance overhead.
  • Use “static includes” when a JSP page does not change very often. For the pages, which change frequently, use dynamic includes.
  • The “dynamic include” (jsp:include) has a flush attribute. This attribute indicates whether the buffer should be flushed before including the new content.

JSP different scope values

Page: Available to the handling JSP page only. Request: Available to the handling JSP page or Servlet and forwarded JSP page or Servlet. Session: Available to any JSP Page or Servlet within the same session. Application: Available to all the JSP pages and Servlets within the same Web Application.

JSP Scripting Elements

SAD
  • Scripting Elements: embedded Java statements.
  • Declaration Element: is the embedded Java declaration statement, which gets inserted at the Servlet class level, so it is not thread safe. <%! %>
  • Expression Element: is the embedded Java expression, which gets evaluated by the service method. <%= %>
  • Scriptlet Elements: are the embedded Java statements, which get executed as part of the service method. <% %>
  • Action Elements: A JSP element that provides information for execution phase.
  • Directive Elements: A JSP element that provides global information for the translation phase.
<%@ page import=”java.util.Date” %> <%@ include file=”myJSP” %> <%@ taglib uri=”tagliburi” prefix=”myTag”%>

life cycle methods of a JSP

  • Pre-translated: Before the JSP file has been translated and compiled into the Servlet.
  • Translated: The JSP file has been translated and compiled as a Servlet.
  • Initialized: Prior to handling the requests in the service method the container calls the jspInit() to initialize the Servlet. Called only once per Servlet instance.
  • Servicing: Services the client requests. Container calls this method for each request.
  • Out of service: The Servlet instance is out of service. The container calls the jspDestroy() method.

URL mapping

http://localhost:8080/myApps/mine/test.do
  • web.xml
MyServlet< /servlet-name> myPath.MyServ let MyServlet< /servlet-name> mine/*.do
  • application.xml
............ m yAppsWeb.wa r< /web-u ri> myApps< /con text-root> < /module> ........ myEJB.jar < /module> .....

J2EE design pattern

Composite View: include sub views View Helper: JavaBean, Custom Tags Service Helper and Dispatcher View:

Core J2EE Patterns - Service to Worker revisit

Front Controller

  • Apply the common logic (security check, flow control), which is shared by multiple requests in the Front controller.
  • Separate the system processing logic from the view processing logic.
  • Provides a controlled and centralized access point for your system.

Declarative Security

PrivateAndSensitive /private/* executive admin FORM /login.jsp /error.jsp The user will be prompted for the configured login.jsp when restricted resources are accessed. The container also keeps track of which users have been previously authenticated.

Filter

  • A filter dynamically intercepts requests and responses to transform or use the information contained in the requests or responses but typically do not themselves create responses.
  • Filters improve reusability by placing recurring tasks in the filter as a reusable unit.
  • The filters can be used for
    • caching and compressing content,
    • logging and auditing,
    • image conversions (scaling up or down etc),
    • authenticating incoming requests,
    • XSL transformation of XML content,
    • localization of the request and the response,
    • site hit count etc.
  • The filters are configured through the web.xml file as follows:
HitCounterFilter myPkg.HitCounterFilter HitCounterFilter /usersection/* ...
  • Servlet filters use the slightly modified version of the chain of responsibility design pattern.

Session replication

Session replication occurs when we replicate the information (ie session attributes) that are stored in your HttpSession. The container propagates the changes only when you call the setAttribute method. So mutating the objects in a session and without calling the setAttribute will not replicate the state change.

servlet clustering

  • 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().

sendRedirect() vs. forward

sendRedirect
  • Sends a header back to the browser, which contains the name of the resource to be redirected to. The browser will make a fresh request from this header information.
  • Need to provide absolute URL path.
  • Has an overhead of extra remote trip.
  • but has the advantage of being able to refer to any resource on the same or different domain
  • also allows book marking of the page.
forward
  • Forward action takes place within the server without the knowledge of the browser.
  • No extra network trip.

RequestDispatcher

ServletContext sc = getServletContext(); RequestDispatcher rd = sc.getRequestDispatcher(url); rd.forward(request,response); rd.include(request, response);

Lazy loading 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.

Thread Safe Servlet

  • A typical Servlet life cycle creates a single instance of each servlet and creates multiple threads to handle the service() method. The multithreading aids efficiency but the servlet code must be coded in a thread safe manner. The shared resources (e.g. instance variables, utility or helper objects etc) should be appropriately synchronized or should only use variables in a read-only manner.
  • Alternatively it is possible to have a single threaded model of a servlet by implementing SingleTreadModel.
  • The container will 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: It is best practice to use multi-threading and stay away from the single threaded model of the servlet unless otherwise there is a compelling reason for it.

HttpServlet vs GenericServlet

  • Generic Servlet: Protocol independent, service() method
  • HttpServlet: Protocol dependent, doGet(), doPost(), doHead() methods.

Servlet Config vs. Servlet Context


The ServletConfig parameters are for a particular Servlet.
HttpServlet extends GenericServlet implements ServletConfig, myServlet.getInitParameter(paramName)
<servlet>
<servlet-name>MyServlet1</servlet-name>
<servlet-class>com.MyServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/config/config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
The ServletContext parameters are specified for the entire Web application.

In the case of a web application marked "distributed" in its deployment descriptor, there will be one context instance for each virtual machine. In this situation, the context cannot be used as a location to share global information (because the information won't be truly global). Use an external resource like a database instead. The ServletContext object is contained within the ServletConfig object, which the Web server provides the servlet when the servlet is initialized. Servlet.getServletConfig(), ServletConfig.getServletContext()

<context-param>
<param-name>GlobalClassName</param-name>
<param-value>MyWebAppClass</param-value>
</context-param>

web structure

  • A public resource directory (document root): The document root is where JSP pages, client-side classes and archives, and static Web resources are stored.
  • A private directory called WEB-INF: which contains following files and directories:
    • web.xml : Web application deployment descriptor.
    • *.tld : Tag library descriptor files.
    • classes : A directory that contains server side classes like servlets, utility classes, JavaBeans etc.
    • lib : A directory where JAR (archive files of tag libraries, utility libraries used by the server side classes) files are stored.
  • Note: JSP resources usually reside directly or under subdirectories of the document root, which are directly accessible to the user through the URL. If you want to protect your Web resources then hiding the JSP files behind the WEB-INF directory can protect the JSP files from direct access.

Servlet Reload

  • Development/Test: deployed to  $server_root/servlets and timestamp comparison for each request comes in and a new custom classloader is created for reloading the new servlet.
  • Production: deployed to $server_root/classes
When a server dispatches a request to a servlet, the server first checks if the servlet's class file has changed on disk. If it has changed, the server abandons the class loader used to load the old version and creates a new instance of the custom class loader to load the new version. Old servlet versions can stay in memory indefinitely (so the effect is the other classes can still hold references to the old servlet instances, causing odd side effects, but the old versions are not used to handle any more requests. Servlet reloading is not performed for classes found in the server's classpath because the core, primordial class loader, loads those classes. These classes are loaded once and retained in memory even when their class files change.

Life cycle of a servlet

  • instantiate and init(): ready state
  • service(): spawn thread
  • destroy: for gc

Maintain state for stateless HTTP

HTTP Session: no size limit, need to remove session, set time out, serialize. Hidden field: no size limit, expose private Cookie: size limit, expose private, might be turned off. URL rewriting: size limit, expose private

CGI vs Servlet

  • CGI Common Gateway Interface, creates a heavy weight process to handle each http request. N number of copies of the same traditional CGI programs is copied into memory to serve N number of requests.
  • Servlet: Spawns a lightweight Java thread to handle each http request. Single copy of a type of servlet but N number of threads (thread sizes can be configured in an application server). In MVC, servlets process requests and select JSP views. So servlets act as controller.

web.xml

display-name
context-param
servlet: servlet-name, servlet-class, init-param
servlet-mapping: servlet-name, url-pattern
error-page: error-code, location
taglib: tablig-uri, taglib-location
security-constraint: web-resource-collection, auth-constraint
login-config: auth-method, realm-name, form-login-config
security-role

EJB classloader vs. WAR classloader

  • EJB jars in the application share the same EJB class loader.
  • WAR files get their own class loader.
This is because the EJBs have inherent relationship between one another (ie EJB-EJB communication between EJBs in different applications but hosted on the same JVM) but the Web modules do not. Every WAR file should be able to have its own WEB-INF/lib third party libraries and need to be able to load its own version of converted logon.jsp Servlet so each WEB module is isolated in its own class loader.

So if two different WEB modules want to use two different versions of the same EJB then we need to have two different ear files. In Java section the class loaders use a delegation model where the child class loaders delegate the loading up the hierarchy to their parent before trying to load it itself only if the parent can’t load it. But with regards to WAR class loaders, some application servers provide a setting to turn this behaviour off (DelegationMode=false). This delegation mode is recommended in the Servlet 2.3 specification. 

J2EE classloader

  • Above System-Classpath classloader: Children can see parent.
  • Below System-Classpath classloader: Children can see parent only if it is mentioned in MANIFEST.MF
J2EE application specific class loaders are children of the System-Classpath classloader. This class loader is responsible for loading all the dependency jar files (log4j, util.jar, common.jar), which are shared by both WEB and EJB modules. So if EJB.jar wants to refer to Common.jar and Util.jar we need to add them (space delimited) to class-path in EJB.jar’s manifest file MANIFEST.MF.
As a general rule classes should not be deployed higher in the hierarchy than they are supposed to exist. This is because if you move one class up the hierarchy then you will have to move other classes up the hierarchy as well. This is because classes loaded by the parent class loader can’t see the classes loaded by its child class loaders (uni-directional bottom-up visibility).

ejb_jar.xml

enterprise-beans
  • session: ejb-name, home, remote, ejb-class, session-type, transaction-type
  • entity: ejb-name, home, remote, ejb-class, persistence-type, prim-key-class, reentrant, cmp-field
assembly-descriptor
  • security-role
  • method-permission
  • container-transaction

application.xml

  • EJB jar modules, WEB war modules, <security-role> etc.
  • Also since EJB jar modules are packaged as jars the same way dependency libraries like log4j.jar, commonUtil.jar etc are packaged, the application.xml descriptor will distinguish between these two jar files by explicitly specifying the EJB jar modules.

Web Server vs. App Server

Web Server:
  • Supports HTTP protocol. When the Web server receives an HTTP request, it responds with an HTTP response, such as sending back an HTML page (static content) or delegates the dynamic response generation to some other program such as CGI scripts or Servlets or JSPs in the application server.
  • Uses various scalability and fault-tolerance techniques.
App Server:
  • Exposes business logic and dynamic content to the client through various protocols such as HTTP, TCP/IP, IIOP, JRMP etc.
  • Uses various scalability and fault-tolerance techniques. In addition provides resource pooling, component life cycle management, transaction management, messaging, security etc.
  • Provides services for components like Web container for servlet components and EJB container for EJB components.
With the advent of XML Web services the line between application servers and Web servers is not clear-cut. By passing XML documents between request and response the Web server can behave like an application server.

J2EE Design Patterns

http://java.sun.com/blueprints/patterns/catalog.html Filter, Front Controller, View Helper, Composite View, Dispatcher View, Service To Worker, Business Delegate, Session Facade, Service Locator, Transfer Object Assembler, Value List Handler, Composite Entity, Transfer Object, DAO, Service Activator.

Structure of ear file

App.ear
  • META-INF
    • MANIFEST.MF
    • application.xml
  • EJB.jar
    • META-INF
      • MANIFEST.MF
      • ejb-jar.xml
    • ejb classes, non-ejb classes
  • Web.war
    • META-INF
      • MANIFEST.MF
    • WEB-INF
      • web.xml
      • lib
      • classes
    • JSP, HTML, CSS, JS
  • Common.jar, Util.jar
  • 3Party.jar

how classes are found

 

jar shared by web and EJB modules

MANIFEST.MF files Manifest-Version: 1.0 Created-By: Apache Ant 1.5 Class-Path: myAppsUtil.ja

MVC 2

Model (EJB, Plain Java Classes)
  • Encapsulates business logic and application state.
View (JSP, JavaBeans, SWING, Custom Tags, etc )
  • Renders the model & has only display logic.
  • Sends user actions to the controller
  • Allows controller to select a view.
Controller (Servlet, Struts Action etc)
  • controls application behavior
  • Maps user actions to model.
  • selects view for response.
  • usually one for each functionality.

MVC

  • A model represents the core business logic and state. A model commonly maps to data in the database and will also contain core business logic.
  • A View renders the contents of a model. A view accesses the data from the model and adds display logic to present the data.
  • A Controller acts as the glue between a model and a view. A controller delegates the request to the model for application logic and state and also centralises the logic for dispatching the request to the next view based on the input parameters from the client and the application state. A controller also decouples JSP pages and the Servlet by handling the view selection.

Key benefits of multitier J2EE

  • Manageability: Each tier can be monitored, tuned and upgraded independently and different people can have clearly defined responsibilities.
  • Scalability: More hardware can be added and allows clustering (i.e. horizontal scaling).
  • Maintainability: Changes and upgrades can be performed without affecting other components.
  • Availability: Clustering and load balancing can provide availability.
  • Extensibility: Additional features can be easily added.

Multitier

  • Client tier represents Web browser, a Java or other application, Applet, WAP phone etc. The client tier makes requests to the Web server who will be serving the request by either returning static content if it is present in the Web server or forwards the request to either Servlet or JSP in the application server for either static or dynamic content.
  • Presentation tier encapsulates the presentation logic required to serve clients. A Servlet or JSP in the presentation tier intercepts client requests, manages logons, sessions, accesses the business services, and finally constructs a response, which gets delivered to client.
  • Business tier provides the business services. This tier contains the business logic and the business data. All the business logic is centralised into this tier as opposed to 2-tier systems where the business logic is scattered between the front end and the backend. The benefit of having a centralised business tier is that same business logic can support different types of clients like browser, WAP, other stand-alone applications etc.
  • Integration tier is responsible for communicating with external resources such as databases, legacy systems, ERP systems, messaging systems like MQSeries etc. The components in this tier use JDBC, JMS, J2EE Connector Architecture (JCA) and some proprietary middleware to access the resource tier.
  • Resource tier is the external resource such as a database, ERP system, Mainframe system etc responsible for storing the data. This tier is also known as Data Tier or EIS (Enterprise Information System) Tier.

advantage of multitier artchitecture

The advantages of the multi-tier architecture are:
  • Forced separation of user interface logic and business logic.
  • Business logic sits on small number of centralized machines (may be just one).
  • Easy to maintain, to manage, to scale, loosely coupled etc.

J2EE API

Component model technology: Java Servlet, JavaServer Pages(JSP), Enterprise JavaBeans(EJB).
Web services technology:
  • JAXP (Java API for XML Processing),
  • JAXR (Java API for XML Registries),
  • SAAJ (SOAP with attachment API for Java),
  • JAX-RPC (Java API for XML-based RPC),
  • JAX-WS (Java API for XML-based Web Services).
Other:
  • JDBC (Java Database Connectivity),
  • JNDI (Java Naming and Directory Interface),
  • JMS (Java Messaging Service),
  • JCA (J2EE Connector Architecture),
  • JTA (Java Transaction API), JavaMail,
  • JAF (JavaBeans Activation Framework – used by JavaMail),
  • JAAS (Java Authentication and Authorization Service),
  • JMX (Java Management eXtenstions).

Protocols

Protocols are used for access to Internet services. J2EE platform supports:
  • HTTP (HyperText Transfer Protocol),
  • TCP/IP (Transmission Control Protocol / Internet Protocol),
  • RMI (Remote Method Invocation),
  • SOAP (Simple Object Access Protocol) and
  • SSL (Secured Socket Layer) protocol.

J2EE server

A J2EE server provides system level support services such us security, transaction management, JNDI lookups, remote access etc. J2EE architecture provides configurable and nonconfigurable services. The configurable service enables the J2EE components within the same J2EE application to behave differently based on where they are deployed. For example the security settings can be different for the same J2EE application in two different production environments. The non-configurable services include enterprise bean (EJB) and servlet life cycle management, resource pooling etc.

J2EE container

Containers (Web & EJB containers) are the interface between a J2EE component and the low level platform
specific functionality that supports J2EE components. Before a Web, enterprise bean (EJB), or application client
component can be executed, it must be assembled into a J2EE module (jar, war, and/or ear) and deployed into its
container.

component vs service

A component is an application level software unit. All the J2EE components depend on the container for the system
level support like transactions, security, pooling, life cycle management, threading etc. A service is a component
Enterprise Java that can be used remotely through a remote interface either synchronously or asynchronously (e.g. Web service, messaging system, sockets, RPC etc).

J2EE component

A J2EE component is a self-contained functional software unit that is assembled into a J2EE application with its
related classes and files and communicates with other components. The J2EE specification defines the following
J2EE components: Applet, Web component (Servlet, JSP), EJB (Session, Entity, Message), Enterprise application, Resource adapters.

What is J2EE

J2EE is an environment for developing and deploying enterprise applications. The
J2EE platform consists of J2EE components, servicesAPIs and protocols
that provide the functionality for developing multi-tiered and distributed Web based applications.

Core Dump

The JVM is a process like any other and when a process crashes a core dump is created. A core dump is a memory map of a running process. This can happen due to one of the following reasons:
  • Using JNI (Java Native Interface) code, which has a fatal bug in its native code. Example: using Oracle OCI drivers, which are written partially in native code or jdbc-odbc bridge drivers, which are written in non Java code. Using 100% pure Java drivers (communicates directly with the database instead of through client software utilizing the JNI) instead of native drivers can solve this problem. We can use Oracle thin driver, which is a 100% pure Java driver.
  • The operating system on which your JVM is running might require a patch or a service pack.
  • The JVM implementation you are using may have a bug in translating system resources like threads, file handles, sockets etc from the platform neutral Java byte code into platform specific operations. If this JVM’s translated native code performs an illegal operation then the operating system will instantly kill the process and mostly will generate a core dump file, which is a hexadecimal file indicating program’s state in memory at the time of error. The core dump files are generated by the operating system in response to certain signals. Operating system signals are responsible for notifying certain events to its threads and processes. The JVM can also intercept certain signals like SIGQUIT which is kill -3 <> from the operating system and it responds to this signal by printing out a Java stack trace and then continue to run. The JVM continues to run because the JVM has a special built-in debug routine, which will trap the signal -3. On the other hand signals like SIGSTOP (kill -23 ) and SIGKILL (kill -9 ) will cause the JVM process to stop or die. The following JVM argument will indicate JVM not to pause on SIGQUIT signal from the operating system. Java –Xsqnopause

Reasons to cause OutOfMemoryError

  • JVM may have a memory leak due to a bug in its internal heap management implementation. But this is highly unlikely because JVMs are well tested for this.
  • The application may not have enough heap memory allocated for its running. You can allocate more JVM heap size (with –Xmx parameter to the JVM) or decrease the amount of memory your application takes to overcome this. To increase the heap space: Java -Xms1024M -Xmx1024M Care should be taken not to make the –Xmx value too large because it can slow down your application. The secret is to make the maximum heap size value the right size.
  • Another not so prevalent cause is the running out of a memory area called the “perm” which sits next to the heap. All the binary code of currently running classes is archived in the “perm” area. The ‘perm’ area is important if your application or any of the third party jar files you use dynamically generate classes. For example: “perm” space is consumed when XSLT templates are dynamically compiled into classes, J2EE application servers, JasperReports, JAXB etc use Java reflection to dynamically generate classes and/or large amount of classes in your application. To increase perm space: Java -XX:PermSize=256M -XX:MaxPermSize=256M
  • you may have a memory leak in your application.

OutOfMemoryError

Any problem in pure Java code throws a Java exception or error. Java exceptions or errors will not cause a core dump (on UNIX systems) or a Dr.Watson error (on WIN32systems). Any serious Java problem will result in an OutOfMemoryError thrown by the JVM with the stack trace and consequently JVM will exit. These Java stack traces are very useful for identifying the cause for an abnormal exit of the JVM. So is there a way to know that OutOfMemoryError is about to occur? The Java JDK 1.5 has a package called java.lang.management which has useful JMX beans that we can use to manage the JVM. One of these beans is the MemoryMXBean.

Key Points

Minimising memory leaks

  • Design applications with an object’s life cycle in mind, instead of relying on the clever features of the JVM. Letting go of the object’s reference in one’s own class as soon as possible can mitigate memory problems. Example: myRef = null;
  • Unreachable collection objects can magnify a memory leak problem. In Java it is easy to let go of an entire collection by setting the root of the collection to null. The garbage collector will reclaim all the objects (unless some objects are needed elsewhere).
  • Use weak references if you are the only one using it. The WeakHashMap is a combination of HashMap and WeakReference. This class can be used for programming problems where you need to have a HashMap of information, but you would like that information to be garbage collected if you are the only one referencing it.
  • Free native system resources like AWT frame, files, JNI etc when finished with them. Example: Frame, Dialog, and Graphics classes require that the method dispose() be called on them when they are no longer used, to free up the system resources they reserve.

Detect memory leaks

  • Use tools like JProbe, OptimizeIt etc to detect memory leaks.
  • Use operating system process monitors like task manager on NT systems, ps, vmstat, iostat, netstat etc on UNIX systems.
  • Write your own utility class with the help of totalMemory() and freeMemory() methods in the Java Runtime class.
  • An even better approach than a utility class is using dynamic proxies or Aspect Oriented Programming (AOP) for pre and post memory recording where you have the control of activating memory measurement only when needed.

Performance Tips

  • Use ArrayLists, HashMap etc as opposed to Vector, Hashtable etc where possible. This is because the methods in ArrayList, HashMap etc are not synchronized.Even better is to use just arrays where possible.
  • Set the initial capacity of a collection (e.g. ArrayList, HashMap etc) and StringBuffer/StringBuilder appropriately. This is because these classes must grow periodically to accommodate new elements. So, if you have a very large ArrayList or a StringBuffer, and you know the size in advance then you can speed things up by setting the initial size appropriately.
  • Minimise the use of casting or runtime type checking like instanceof in frequently executed methods or in loops. The “casting” and “instanceof” checks for a class marked as final will be faster. Using “instanceof” construct is not only ugly but also unmaintainable. Look at using visitor pattern.
  • Do not compute constants inside a large loop. Compute them outside the loop. For applets compute it in the init() method.
  • Exception creation can be expensive because it has to create the full stack trace. The stack trace is obviously useful if you are planning to log or display the exception to the user. But if you are using your exception to just control the flow, which is not recommended, then throw an exception, which is precreated. An efficient way to do this is to declare a public static final Exception in your exception class itself.
  • Avoid using System.out.println and use logging frameworks like Log4J etc, which uses I/O buffers
  • Minimize calls to Date, Calendar, etc related classes.
  • Minimize JNI calls in your code.

Minimize the creation of objects

  • If repeating code within a loop, avoid creating new objects for each iteration. Create objects before entering the loop (i.e. outside the loop) and reuse them if possible.
  • For complex objects that are used frequently, consider creating a pool of recyclable objects rather than always instantiating new objects. This adds additional burden on the programmer to manage the pool, but in select cases can represent an order of magnitude performance gain.
  • Use lazy initialization when you want to distribute the load of creating large amounts of objects.

Performance

  • Pool valuable system resources like threads, database connections, socket connections etc. Emphasis on reuse of threads from a pool of threads. Creating new threads and discarding them after use can adversely affect performance. Also consider using multi-threading in your single-threaded applications where possible to enhance performance. Optimze the pool sizes based on system and application specifications and requirements.
  • Optimize your I/O operations: use buffering when writing to and reading from files and/or streams. Avoid writers/readers if you are dealing with only ASCII characters. You can use streams instead, which are faster. Avoid premature flushing of buffers. Also make use of the performance and scalability enhancing features such as non-blocking and asynchronous I/O, mapping of file to memory etc offered by the NIO (New I/O).
  • Minimize network overheads by retrieving several related items simultaneously in one remote invocation if possible. Remote method invocations involve a network round-trip, marshalling and unmarshalling of parameters, which can cause huge performance problems if the remote interface is poorly designed.
  • Establish whether you have a potential memory problem and manage your objects efficiently: remove references to the short-lived objects from long-lived objects like Java collections etc to minimise any potential memory leaks. Also reuse objects where possible. It is cheaper to recycle objects than creating new objects each time. Avoid creating extra objects unnecessarily. For example use mutable StringBuffer/StringBuilder classes instead of immutable String objects in computation expensive loops. Automatic garbage collection is one of the most highly touted conveniences of Java. However, it comes at a price. Creating and destroying objects occupies a significant chunk of the JVM's time.

Call Web Server from Java

URLConnection (HttpURLConnection and JarURLConnection.) or HttpClient (browser). They both Supports HEAD, GET, POST, PUT, DELETE, TRACE and OPTIONS, but not cookies.

Socket

  • A socket is a communication channel, which facilitates inter-process communication (For example communicating between two JVMs, which may or may not be running on two different physical machines).
  • There are two kinds of sockets: The connectionless communication protocol of the Internet is called UDP (datagram sockets). The connection-oriented communication protocol of the Internet is called TCP.
  • Each socket is uniquely identified on the entire Internet with two numbers: 128-bit integer called the Internet Address (or IP address) and a 16-bit integer called the port of the socket.
  • The port numbers 0 to 1023 are reserved for standard services such as e-mail, FTP, HTTP etc.
  • The lifetime of the socket is made of 3 phases: Open Socket-->Read and Write to Socket-->Close Socket. In Java you can use the Socket (client side) and ServerSocket (Server side) classes.

Singleton & Factory

Another important aspect to consider when writing your factory class is that, it does not make sense to create a new factory object for each invocation you can incorporate the singleton design pattern into your factory pattern code. The singleton design pattern will create only a single instance of your SimpleShapeFactory class. Since an abstract factory pattern is unlike factory pattern, where you need to have an instance for each of the two factories (i.e.SimpleShapeFactory and ComplexShapeFactory) returned, you can still incorporate the singleton pattern as an access point and have an instance of a HashMap, store your instances of both factories. Now your calling method uses a static method to get the same instance of your factory, hence conserving memory and promoting object
reuse:
ShapeFactory factory = ShapeFactory. GetFactoryInstance();
factory.getShape(1);

Benefits of Factory Pattern

  • The factory pattern decoupling or the dependencies between the calling code and called objects like Circle, Square etc. Factory pattern returns an instance of several (product hierarchy) subclasses (like Circle, Square etc), but the calling code is unaware of the actual implementation class. The calling code invokes the method on the interface (for example Shape) and using polymorphism the correct draw() method gets invoked.
  • You do not have to create a new Circle or a new Square on each invocation as shown in the sample code, which is for the purpose of illustration and simplicity. In future, to conserve memory you can decide to cache objects or reuse objects in your factory with no changes required to your calling code. You can also load objects in your factory based on attribute(s) read from an external properties file or some other condition.
  • Another benefit going for the factory is that unlike calling constructors directly, factory patterns have more meaningful names like getShape(…), getInstance(…) etc, which may make calling code more clear.

Factory Method/Abstract Factory

A Factory method pattern (aka Factory pattern) is a creational pattern. The creational patterns abstract the
object instantiation process by hiding how the objects are created and make the system independent of the object
creation process. An Abstract factory pattern is one level of abstraction higher than a factory method pattern,
which means it returns the factory classes.
 
Factory pattern returns one of the several product subclasses. You should use a factory pattern If you have a super class and a number of subclasses,and based on some data provided, you have to return the object of one of the subclasses.
An Abstract factory pattern is one level of abstraction higher than a factory method pattern, which means the abstract factory returns the appropriate factory classes, which will later on return one of the product subclasses.
 

case-insensitive string sort

Collections.sort(stringList, String.CASE_INSENSITIVE_ORDER);

Singleton

A singleton is a class that can be instantiated only one time in a JVM per class loader. Repeated calls always return the same instance. Ensures that a class has only one instance, and provide a global point of access. It can be an issue if singleton class gets loaded by multiple class loaders.
private static variable, private construtor, public static getInstance.

public class OnlyOne {
    private static OnlyOne one = new OnlyOne();
    private OnlyOne(){… } //private constructor. This class cannot be instantiated from outside.
    public static OnlyOne getInstance() {
        return one;
    }
}
When to use: Use it when only a single instance of an object is required in memory for a single point of access.
  • Accessing application specific properties through a singleton object, which reads them for the first time from a properties file and subsequent accesses are returned from in-memory objects. Also there could be another piece of code, which periodically synchronizes the in-memory properties when the values get modified in the underlying properties file. This piece of code accesses the in-memory objects through the singleton object (i.e. global point of access).
  • Accessing in-memory object cache or object pool, or non-memory based resource pools like sockets, connections etc through a singleton object (i.e. global point of access).

Threads block on I/O

When threads are blocked (say due to time consuming reads or writes) on an I/O call inside an object’s synchronized method and also if the other methods of the object are also synchronized then the object is essentially frozen while the thread is blocked.
Be sure to not synchronize code that makes blocking calls, or make sure that a non-synchronized method exists on an object with synchronized blocking code. Although this technique requires some care to ensure that the resulting code is still thread safe, it allows objects to be responsive to other threads when a thread holding its locks is blocked.
Note: The java.nio.* package was introduced in JDK1.4. The coolest addition is nonblocking I/O (aka NIO that stands for New I/O).

2 synchronized methods in one object

If 2 different threads hit 2 different synchronized methods in an object at the same time will they both continue?  No. Only one method can acquire the lock.

Thread communication

  • The wait(), notify(), and notifyAll() methods are used to provide an efficient way for threads to communicate with each other. This communication solves the ‘consumer-producer problem’. This problem occurs when the producer thread is completing work that the other thread (consumer thread) will use.
  • wait and notify should be placed within synchronized code to ensure that the current code owns the monitor

  • The notify method will wake up one thread waiting to reacquire the monitor for the object. You cannot be certain which thread gets woken. If you have only one waiting thread then you do not have a problem. If you have multiple waiting threads then it will probably the thread that has been waiting the longest that will wake up. However you cannot be certain, and the priorities of the threads will influence the result. As a result you are generally advised to use notifyAll instead of notify, and not to make assumptions about scheduling or priorities. Of course this is not always possible and you may have to try to test your code on as many platforms as possible.

daemon thread

Daemon threads are sometimes called "service" threads. These are threads that normally run at a low priority and provide a basic service to a program or programs when activity on a machine is reduced. An example of a daemon thread that is continuously running is the garbage collector thread. This thread is provided by the JVM.

synchronization level

  • method: synchronize aMethod() {}
  • statement: synchronize(anyObject) {}
  • Often using a lock on a method level is too coarse. Why lock up a piece of code that does not access any shared resources by locking up an entire method. Since each object has a lock, dummy objects can be created to implement block level synchronization. The block level is more efficient because it does not lock the whole method.

thread, lock, monitor

thread synchronization A monitor is like a building that contains one special room that can be occupied by only one thread at a time. The room usually contains some data. From the time a thread enters this room to the time it leaves, it has exclusive access to any data in the room.
  • Entering the monitor building is called "entering the monitor."
  • Entering the special room inside the building is called "acquiring the monitor."
  • Occupying the room is called "owning the monitor,"
  • and leaving the room is called "releasing the monitor."
  • Leaving the entire building is called "exiting the monitor."
In addition to being associated with a bit of data, a monitor is associated with one or more bits of code, which in this book will be called monitor regions. To implement the mutual exclusion capability of monitors, the Java virtual machine associates a lock (sometimes called a mutex) with each object and class. A lock is like a privilege that only one thread can "own" at any one time. Threads need not obtain a lock to access instance or class variables. If a thread does obtain a lock, however, no other thread can obtain a lock on the same data until the thread that owns the lock releases it. Note that as a Java programmer, you never explicitly lock an object. Object locks are internal to the Java virtual machine. In your Java programs, you identify the monitor regions of your program by writing synchronized statements and methods. As the Java virtual machine runs your program, it automatically locks an object or class every time it encounters a monitor region. We have seen that critical sections are guarded by monitors and only the thread which has a lock associated with that monitor can access the resources in that critical section. In simple terms, consider a synchronized method or a synchronized block of code. Any thread before executing that code takes the lock over the object, the object in case of the synchronized method is the instance on which the synchronized method is called; in case of a synchronized block, it could any other object whose reference is given there. For example, synchronized (anyObject) { }.

yield vs sleep (thread)

When a task invokes yield(), it changes from running state to runnable state. When a task invokes sleep(), it changes from running state to waiting/sleeping state.

Thread states

  • Runnable — waiting for its turn to be picked for execution by the thread schedular based on thread priorities.
  • Running: The processor is actively executing the thread code. It runs until it becomes blocked, or voluntarily gives up its turn with this static method Thread.yield(). Because of context switching overhead, yield() should not be used very frequently.
  • Waiting: A thread is in a blocked state while it waits for some external processing such as file I/O to finish.
  • Sleeping: Java threads are forcibly put to sleep (suspended) with this overloaded method: Thread.sleep(milliseconds), Thread.sleep(milliseconds, nanoseconds);
  • Blocked on I/O: Will move to runnable after I/O condition like reading bytes of data etc changes.
  • Blocked on synchronization: Will move to Runnable when a lock is acquired.
  • Dead: The thread is finished working.

Creation of thread

  • extends Thread. Thread t = new ExtendThread();
  • implements Runnable. Thread t = new Thread(new ImplementRunnable());
t.start() The runnable interface is preferred, as it does not require your object to inherit a thread because when you need multiple inheritance, only interfaces can help you.

Process/Thread

A process is an execution of a program but a thread is a single execution sequence within the process. A process can contain multiple threads. A thread is sometimes called a lightweight process. A JVM runs in a single process and threads in a JVM share the heap belonging to that process. That is why several threads may access the same object. Threads share the heap and have their own stack space. This is how one thread’s invocation of a method and its local variables are kept thread safe from other threads. But the heap is not thread-safe and must be synchronized for thread safety.

throw/throws

throw new MyException(“I threw my own exception.”) To declare an exception: public myMethod() throws MyException {…} throws in the method signature.

Best Practice for exception handling

  • Catch subclass exception first.
  • Throw an exception early
The exception stack trace helps you pinpoint where an exception occurred by showing us the exact sequence of method calls that lead to the exception. By throwing your exception early, the exception becomes more accurate and more specific. Use if(file==null) throw new IllegalArgumentException instead of new FileInputStream(file)
  • Avoid suppressing or ignoring exceptions.
  • Also avoid using exceptions just to get a flow control.
  • Catch the exception at the appropriate layer
You should not try to catch the exception before your program can handle it in an appropriate manner. The natural tendency when a compiler complains about a checked exception is to catch it so that the compiler stops reporting errors. The best practice is to catch the exception at the appropriate layer (e.g. an exception thrown at an integration layer can be caught at a presentation layer in a catch {} block), where your program can either meaningfully recover from the exception and continue to execute or log the exception only once in detail, so that user can identify the cause of the exception. Note: Due to heavy use of checked exceptions and minimal use of unchecked exceptions, there has been a hot debate in the Java community regarding true value of checked exceptions.
  • Use checked exceptions when the client code can take some useful recovery action
  • Use unchecked exception when client code cannot do anything based on information in exception.
For example, convert your SQLException into another checked exception if the client code can recover from it and convert your SQLException into an unchecked (i.e. RuntimeException) exception, if the client code cannot do anything about it.

Exception

All the exceptions except RuntimeException are compiler checked exceptions. If a method is capable of throwing a checked exception it must declare it in its method header or handle it in a try/catch block. Failure to do so raises a compiler error. So checked exceptions can, at compile time, greatly reduce the occurrence of unhandled exceptions surfacing at runtime in a given application at the expense of requiring large throws declarations and encouraging use of poorly constructed try/catch blocks. A RuntimeException class represents exceptions that occur within the Java virtual machine (during runtime). NullPointerException, ArrayOutOfBoundException. The cost of checking for the runtime exception often outweighs the benefit of catching it. Attempting to catch or specify all of them all the time would make your code unreadable and unmaintainable. The compiler allows runtime exceptions to go uncaught and unspecified. If you like, you can catch these exceptions just like other exceptions. However, you do not have to declare it in your “throws" clause or catch it in your catch clause. In addition, you can create your own RuntimeException subclasses and this approach is probably preferred at times because checked exceptions can complicate method signatures and can be difficult to follow.

PreparedStatement

http://forum.java.sun.com/thread.jsp?forum=48&thread=538747&tstart=0&trange=15 A prepared statement gets compiled by the database during the first execution. Most databases have a query cache, and the query will stay there for a while. So, the next invocation of the statement won't need to be recompiled by the database (if it still is in the cache). That will speed things up. The best reasons for using PreparedStatements are these: (1) Executing the same query multiple times in loop, binding different parameter values each time, and (2) Using the setDate()/setString() methods to escape dates and strings properly, in a database-independent way. (3) SQL injection attacks on a system are virtually impossible when using Prepared Statements. I have read the statement has less initial overhead so its better for a one time call - for instance to get some information to populate a combo box. PreparedStatement has more initial overhead but it is dramatically reduced on subsequent calls because its precompiled at the DB so it would be used when you need to execute the same statement repeatedly with different parameters. I don't worry about the performance hit until it becomes a problem. Network latency is usually the bigger problem, and that has to do with the way queries are done rather the Statement vs PreparedStatement.

Try-Catch-Finally

Throw early catch later.

In the normal case, control reaches the end of the try block and then proceeds to the finally block, which performs any necessary cleanup. If control leaves the try block because of a return, continue, or break statement, the finally block is executed before control transfers to its new destination.

If an exception occurs in the try block, and there is an associated catch block to handle the exception, control transfers first to the catch block and then to the finally block. If there is no local catch block to handle the exception, control transfers first to the finally block, and then propagates up to the nearest containing catch clause that can handle the exception.

If a finally block itself transfers control with a return, continue, break, or throw statement or by calling a method that throws an exception, the pending control transfer is abandoned, and this new transfer is processed. For example, if a finally clause throws an exception, that exception replaces any exception that was in the process of being thrown. If a finally clause issues a return statement, the method returns normally, even if an exception has been thrown and has not been handled yet.

try and finally can be used together without exceptions or any catch clauses. In this case, the finally block is simply cleanup code that is guaranteed to be executed, regardless of any break, continue, or return statements within the try clause.

Joins: Innter, Outer,Equi, Natural..

An inner join essentially combines the records from two tables A and B based on a given join predicate. The cross product of all records in table is computed. Thus, each record in table A is combined with every record in table B. Only those records in the joined table that satisfy the join predicate remain. This is the most common type of join used in applications, and is considered the default join type.
 
An equi-join is a specific type of comparator-based join, or theta join, that uses only equality comparisons in the join predicate. Using other comparison operators such as < disqualifies a join as equi-join. The query 2 sections above is already an example for equi-joins.
 
A natural join is a further specialization of equi-joins. The join predicate is implicitly given by comparing all columns in both tables that have the same column name in the tables to be joined. The resulting joined table contains only one column for each pair of equally-named columns.
 
Outer joins do not require that each record in the two joined tables has a matching record in the other table. The record is retained in the joined table if no other matching record exists. Outer joins are subdivided further into left outer joins, right outer joins, and full outer joins, depending from which table the rows shall be retained (left, right, or both).
 
The result of a left outer join for tables A and B always contains all records of the "left" table (A), even if the join condition does not find any matching record in the "right" table (B). This means that if the ON clause matches 0 (zero) records in B, a row in the result will still be returned — but with NULL in each column from B.
 
A right outer join is much like a left outer join, except that the tables are reversed. Every record from the "right" table (B) will be in the joined table at least once. If there is no matching row from the "left" table (A), and NULL will be used for columns from A for those records that have any match in A.
 
A full outer join combines the results of both left and right outer joins. The joined table will contain all records from both tables, and fill in NULLs for missing matches on either side.

garbage collector

  • Each time an object is created in Java, it goes into the area of memory known as heap. The Java heap is called the garbage collectable heap. The garbage collection cannot be forced. The garbage collector runs in low memory situations. When it runs, it releases the memory allocated by an unreachable object. The garbage collector runs on a low priority daemon (background) thread. You can nicely ask the garbage collector to collect garbage by calling System.gc() but you can’t force it.
  • What is an unreachable object? An object’s life has no meaning unless something has reference to it. If you can’t reach it then you can’t ask it to do anything. Then the object becomes unreachable and the garbage collector will figure it out. Java automatically collects all the unreachable objects periodically and releases the memory consumed by those unreachable objects to be used by the future reachable objects.
  • We can use the following options with the Java command to enable tracing for garbage collection events. -verbose:gc reports on each garbage collection event.

type casting

  • Type casting means treating a variable of one type as though it is another type.
  • upcast = implicit, downcast = explicit
  • When up casting primitives as shown below from left to right, automatic conversion occurs. But if you go from right to left, down casting or explicit casting is required. byte 􀃆 short 􀃆 int 􀃆 long 􀃆 float 􀃆 double
  • When it comes to object references you can always cast from a subclass to a superclass because a subclass object is also a superclass object. You can cast an object implicitly to a super class type (i.e. upcasting). If this were not the case polymorphism wouldn’t be possible.
  • You can cast down the hierarchy as well but you must explicitly write the cast and the object must be a legitimate instance of the class you are casting to. The ClassCastException is thrown to indicate that code has attempted to cast an object to a subclass of which it is not an instance. We can deal with the problem of incorrect casting in two ways: Use the exception handling mechanism to catch ClassCastException. Use the instanceof statement to guard against incorrect casting.
  • Design pattern: The “instanceof” and “typecast” constructs are shown for the illustration purpose only. Using these constructs can be unmaintainable due to large if and elseif statements and can affect performance if used in frequently accessed methods or loops. Look at using visitor design pattern to avoid these constructs. (Refer Q11 in How would you go about section…).
  • We can also get a ClassCastException when two different class loaders load the same class because they are treated as two different classes.

Nested Classes

l: TIJ If you don’t need a connection between the inner class object and the outer class object, then you can make the inner class static. This is commonly called a nested class.

Inner classes

l: TIJ The inner class is a valuable feature because it allows you to group classes that logically belong together and to control the visibility of one within the other. However, it’s important to understand that inner classes are distinctly different from composition. the inner class can access methods and fields from the enclosing class as if it owned them. Where should you use inner classes? Code without inner classes is more maintainable and readable. When you access private data members of the outer class, the JDK compiler creates package-access member functions in the outer class for the inner class to access the private members. This leaves a security hole. In general we should avoid using inner classes. Use inner class only when an inner class is only relevant in the context of the outer class and/or inner class can be made private so that only outer class can access it. Inner classes are used primarily to implement helper classes like Iterators, Comparators etc which are used in the context of an outer class.

re-entrant, recursive and idempotent

  • A method in stack is re-entrant allowing multiple concurrent invocations that do not interfere with each other. To be reentrant, a function must hold no static data, must not return a pointer to static data, must work only on the data provided to it by the caller, and must not call non-reentrant functions. http://en.wikipedia.org/wiki/Reentrant
  • A function is recursive if it calls itself. Given enough stack space, recursive method calls are perfectly valid in Java though it is tough to debug. Recursive functions are useful in removing iterations from many sorts of algorithms. All recursive functions are re-entrant but not all re-entrant functions are recursive.
  • Idempotent methods are methods that repeated calls to the same method with the same arguments yield same results. For example clustered EJBs, which are written with idempotent methods, can automatically recover from a server failure as long as it can reach another server.

stack and heap memory

why java is slow http://www.itec.uni-klu.ac.at/~harald/CSE/Content/performance.html http://www.phptr.com/articles/printerfriendly.asp?p=31755&rl=1
  • There are two kinds of memory used in Java. These are called stack memory and heap memory. Stack memory stores primitive types and the addresses of objects. The object values are stored in heap memory.
  • The primitive variables (local method variable) are allocated in the stack, but if they are member variables (i.e. fields of a class), they will be stored in the heap.
  • In Java methods local variables are pushed into stack when a method is invoked and stack pointer is decremented when a method call is completed.
  • In a multi-threaded application each thread will have its own stack but will share the same heap. The stack is threadsafe (each thread will have its own stack) but the heap is not threadsafe unless guarded with synchronisation through your code. This is why care should be taken in your code to avoid any concurrent access issues in the heap space.

final/finally/finalize()

  • final - constant declaration. Refer Q27 in Java section.
  • finally - handles exception. The finally block is optional and provides a mechanism to clean up regardless of what happens within the try block (except System.exit(0) call). Use the finally block to close files or to release other system resources like database connections, statements etc. (Refer Q45 in Enterprise section)
  • finalize() - method helps in garbage collection. A method that is invoked before an object is discarded by the garbage collector, allowing it to clean up its state. Should not be used to release non-memory resources like file handles, sockets, database connections etc because Java has only a finite number of these resources and you do not know when the garbage collection is going to kick in to release these non-memory resources through the finalize() method.

final modifier

A final class can’t be extended i.e. A final class may not be subclassed.
A final method can’t be overridden when its class is inherited.
A final variable can't be changed (i.e. it is a constant).

private constructor

Private constructor is used if you do not want other classes to instantiate the object. The instantiation is done by a public static method within the same class.
Used in the singleton pattern. (Refer Q45 in Java section).
Used in the factory method pattern (Refer Q46 in Java section).
Used in utility classes e.g. StringUtils etc.

static method

Static methods prove useful for creating utility classes, singleton classes and factory methods Utility classes are not meant to be instantiated. Improper coding of utility classes can lead to procedural coding. java.lang.Math, java.util.Collections etc are examples of utility classes in Java.

Static/Instance Variable

Class variables are called static variables. There is only one occurrence of a class variable per JVM per class loader. When a class is loaded the class variables (aka static variables) are initialised.
Instance variables are non-static and there is one occurrence of an instance variable in each class instance (i.e. each object).
A static variable is used in the singleton pattern. (Refer Q45 in Java section). A static variable is used with a final modifier to define constants.

Java Object methods

toString, clone, equals, hashCode, finalize, getClass wait, notify,

shallow/deep clone

Shallow copy: If a shallow copy is performed on object then it is copied but its contained objects are not. The contained objects are affected by changes to cloned object. Java supports shallow cloning of objects by default when a class implements the java.lang.Cloneable interface.
Deep copy: If a deep copy is performed on an object then not only object has been copied but the objects contained within it have been copied as well. Serialization can be used to achieve deep cloning. Deep cloning through serialization is faster to develop and easier to maintain but carries a performance overhead.
 
For example, invoking clone() method on a HashMap returns a shallow copy of HashMap instance, which means the keys and values themselves are not cloned. If you want a deep copy then a simple method is to serialize the HashMap to a ByteArrayOutputSream and then deserialize it. This creates a deep copy but does require that
all keys and values in the HashMap are Serializable. Its primary advantage is that it will deep copy any arbitrary object graph.

Improve IO performance

Minimise accessing the hard disk.
Minimise accessing the underlying operating system.
Minimise processing bytes and characters individually.
1. Use buffering to minimise disk access and underlying operating system. As shown below, with buffering large chunks of a file are read from a disk and then accessed a byte or character at a time. BufferedInputStream, BufferedReader
2. Use the NIO package, if you are using JDK 1.4 or later, which uses performance-enhancing features like buffers to hold data, memory mapping of files, non-blocking I/O operations etc.
3. I/O performance can be improved by minimising the calls to the underlying operating systems. The Java runtime itself cannot know the length of a file, querying the file system for isDirectory(), isFile(), exists() etc must query the underlying operating system.
4. Where applicable caching can be used to improve performance by reading in all the lines of a file into a Java collection class like an ArrayList or a HashMap and subsequently access the data from an in-memory collection instead of the disk.

NIO

The New I/O (NIO): more scalable and better performance Java has long been not suited for developing programs that perform a lot of I/O operations. Furthermore, commonly needed tasks such as file locking, non-blocking and asynchronous I/O operations and ability to map file to memory were not available. Non-blocking I/O operations were achieved through work around such as multithreading or using JNI. The New I/O API (aka NIO) in J2SE 1.4 has changed this situation. A server’s ability to handle several client requests effectively depends on how it uses I/O streams. When a server has to handle hundreds of clients simultaneously, it must be able to use I/O services concurrently. One way to cater for this scenario in Java is to use threads but having almost one-to-one ratio of threads (100 clients will have 100 threads) is prone to enormous thread overhead and can result in performance and scalability problems due to consumption of memory stacks and CPU context switching. To overcome this problem, a new set of non-blocking I/O classes have been introduced to the Java platform in java.nio package.
 
The non-blocking I/O mechanism is built around Selectors and Channels. Channels, Buffers and Selectors are the core of the NIO. A Channel class represents a bi-directional communication channel (similar to InputStrean and OutputStream) between datasources such as a socket, a file, or an application component, which is capable of performing one or more I/O operations such as reading or writing. Channels can be non-blocking, which means, no I/O operation will wait for data to be read or written to the network. The good thing about NIO channels is that they can be asynchronously interrupted and closed. So if a thread is blocked in an I/O operation on a channel, another thread can interrupt that blocked thread. Buffers hold data. Channels can fill and drain Buffers. Buffers replace the need for you to do your own buffer management using byte arrays. There are different types of Buffers like ByteBuffer, CharBuffer, DoubleBuffer, etc. A Selector class is responsible for multiplexing (combining multiple streams into a single stream) by allowing a single thread to service multiple channels. Each Channel registers events with a Selector. When events arrive from clients, the Selector demultiplexes (separating a single stream into multiple streams) them and dispatches the events to corresponding Channels. To achieve non-blocking I/O a Channel class must work in conjunction with a Selector class.

Design pattern: NIO uses a reactor design pattern, which demultiplexes events (separating single stream into multiple streams) and dispatches them to registered object handlers. The reactor pattern is similar to an observer pattern (aka publisher and subscriber design pattern), but an observer pattern handles only a single source of events (i.e. a single publisher with multiple subscribers) where a reactor pattern handles multiple event sources (i.e. multiple publishers with multiple subscribers). The intent of an observer pattern is to define a one-to-many dependency so that when one object (i.e. the publisher) changes its state, all its dependents (i.e. all its
subscribers) are notified and updated correspondingly. Another sought after functionality of NIO is its ability to map a file to memory. There is a specialized form of a
Buffer known as MappedByteBuffer, which represents a buffer of bytes mapped to a file. To map a file to MappedByteBuffer, you must first get a channel for a file. Once you get a channel then you map it to a buffer and subsequently you can access it like any other ByteBuffer. Once you map an input file to a CharBuffer, you can do
pattern matching on the file contents. This is similar to running “grep” on a UNIX file system. Another feature of NIO is its ability to lock and unlock files. Locks can be exclusive or shared and can be held on a contiguous portion of a file. But file locks are subject to the control of the underlying operating system.