Java Code Geeks
Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Sunday, July 25, 2010

Java Lazy initialization and Double Check Locking

According to the post at the javaworld, the double check locking is broken. I agree with the author, lets see what is double-check-locking idiom.
The below code snippet is usually used to initiate some private member variables lazily.



class SomeClass {
  private Resource resource = null;
   public Resource getResource() {
     if (resource == null)
     resource = new Resource();
     return resource;
   }
}

This is a very common use case, for example most of the time, your code might not need to use resource, so why to initiate this variable if it is too costly. Instead only initiate it when necessary.
This however will not work for multi-threaded applications, as there is a potential race condition. Two threads can see that resource is null and one thread override the resource variable initiated by another thread. Simple solution is to use Synchronized access, like

class SomeClass {
   private Resource resource = null;
   public Resource Synchronized getResource() {
     if (resource == null)
     resource = new Resource();
     return resource;
   }
}

But this is now slow because whether the resource is already being initiated or not, any calls to getReource will synchronized all the threads.
The smarter solution is to use Double Checking idiom something like this -



class SomeClass {
   private volatile Resource resource = null;
   public Resource getResource() {
     if (resource == null) {
     synchronized {
       if (resource == null)
       resource = new Resource();
     }
     }
     return resource;
   }
}

However, because of the Memory model of JAVA specification, the above mentioned code might work in one JVM but might fail at times. If you remove the volatile keyword, it is definitely broken, but even if you keep the volatile keyword, it is not certain that it will work.
So what is the solution ? The author at the javaworld mentions that we should avoid the lazy initialization and the following code -



class SomeClass {
   public static Resource resource = new Resource();
}


But the problem with this code is - whether you need or not, resource will be always initialized.

According to me, better way to use lazy initialization is to use "holder-class" idiom as explained in Effective Java by Joshua Bloch. It works like this -


class SomeClass {
   private static class FieldHolder {
     static final Resource field = new Resource();
   }
   public Resource getResource() {
     return FieldHolder.field;
   }
}


There is no synchronization, so no added cost. When the getResource method will be called for the very first time, it initiates the FieldHolder class for the very first time.

Sunday, October 12, 2008

Java's Synchronization support may lead to read/write performance bottlenecks

In order to support multi-threading applications, Java provides "synchronized" keyword. The problem with Java's basic support of synchronization is that - synchronized keyword locks on the object level. For example, if we mark one method of a class as synchronized, then if one thread is inside this method, no other thread can not run any synchronized code of the same object.
lets take an example of a Cache implementation. Lets say we created one hashtable which is the cahche in our application. It caches some objects which are otherwise to be fetched from the database. In order to save the round-trip, some of the objects are read from the database and are cached inside the hashtable. Now as it is a cache, so there will be more reads than writes. If we use synchronized keyword and use the cache object as synchronized object, all reads and writes to this cache will be serialized. Whereas in reality, multiple reads can happen concurrently and can enhance performance.

For a minute, lets think about a database table, most of the time we read from the table and at times we write into the table. If reads are serialized, the whole application will become slower. So database have concept like "shared lock" and "exclusive lock".

Sometimes it become very obvious in case of Java applications also to adopt to this type of "shared lock" and "exclusive lock". Reads from the cache should hold a shared lock and write to it should hold an exclusive lock.

Since Java's native API does not support this one needs to write his own logic to make sure he is following this shared/exclusvie concepts.

Here comes this book which is very handy - "Concurrent Programming in Java: Design Principals and Practices". The author Doug Lea maintains a site http://gee.cs.oswego.edu/dl/ where he has a package called util.concurrent which can perform lot of such locking. These packages are also getting included in JSR166.

Sunday, September 28, 2008

Rule based engines to automatically validate upgrades

It is a headache for install/upgrade developers of an enterprise application, to make sure their product will install/upgrade properly at the customer site. By nature, enterprise applications are far more complex than a simple product because of their distributed nature and different varieties of setup that these enterprise applications usually provide. Now software by nature can fail anywhere as we do not have prior knowledge of the system where it will be installing. For a simple example, we might be having an application which is installing fine on the developers and testers boxes but fails at the customer location just because customer had many "non-active" logical volumes !! which we do not usually have.
So in summary, it is not possible to make sure the product with lot of third party integrations/dependencies will really install properly. One way to attack this problem is to produce a framework which will run before and after the install/upgrade of your application and will make sure that 1) the system is ready to install your application (by checking all pre-requisite patches, third party product versions etc) and 2) perform some basic sanity test of the product after install.
Thinking about it, is not very complex with Java and XML. Lets say developer publish one XML schema where in one can put in "several test" and the output to be looked for in that result is a good idea.

For example, lets say your product X depends upon Oracle version 10g. Now you create one sql file which selects the oracle version from v$version and you mention in the XML rule file to run this sql file and check for a regular expression like "10.2.0.3.0". Your framework can run and check for the proper oracle version. Like this a series of "tests" can be performed using this framework.

The beauty of this solution is, as and when you find more failure conditions of your install/upgrade, you can add more tests in your XML based rule file and make the product more failure proof.