Tuesday, February 12, 2013

Use CountDownLatch as a CyclicBarrier

Following is a program to use CountDownLatch as a CyclicBarrier: (However, unlike CyclicBarrier, CountDownLatch cannot be restarted!) Just to understand how/if CountDownLatch can be used instead of CyclicBarrier.

public class CountDownLatchTry {
      private static CountDownLatch latch = new CountDownLatch(2);

      /**
      * @param args
      */
      public static void main(String[] args) {
            // TODO Auto-generated method stub
            Runnable r1 = new Runnable() {
                  public void run() {
                        System.out.println("T1: Before countDown()");
                        latch.countDown();
                        System.out.println("T1: After countDown()... sleeping");
                        try {
                              Thread.sleep(2000);
                        } catch (InterruptedException e1) {
                              // TODO Auto-generated catch block
                              e1.printStackTrace();
                        }
                        try {
                              latch.await();
                        } catch (InterruptedException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                        }
                        System.out.println("T1: After await()");
                  }
            };
           
            Runnable r2 = new Runnable() {
                  public void run() {
                        System.out.println("T2: Before countDown()");
                        latch.countDown();
                        System.out.println("T2: After countDown()... sleeping");
                        try {
                              Thread.sleep(2000);
                        } catch (InterruptedException e1) {
                              // TODO Auto-generated catch block
                              e1.printStackTrace();
                        }
                        try {
                              latch.await();
                        } catch (InterruptedException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                        }
                        System.out.println("T2: After await()");
                  }
            };

            Thread t1 = new Thread(r1, "T1");
            Thread t2 = new Thread(r2, "T2");
           
            t1.start();
            t2.start();
            System.out.println("Done!");
      }
}

Corresponding CyclicBarrier example:

public class CyclicBarrierTry {

      private static CyclicBarrier cb = new CyclicBarrier(2);
      /**
      * @param args
      */
      public static void main(String[] args) {
            // TODO Auto-generated method stub
           
            Runnable r1 = new Runnable() {
                  public void run() {
                        System.out.println("T1: Before await()");
                        try {
                              cb.await();
                        } catch (InterruptedException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                        } catch (BrokenBarrierException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                        }
                        System.out.println("T1: After await()");
                  }
            };
           
            Runnable r2 = new Runnable() {
                  public void run() {
                        System.out.println("T2: Before await()");
                        try {
                              cb.await();
                        } catch (InterruptedException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                        } catch (BrokenBarrierException e) {
                              // TODO Auto-generated catch block
                              e.printStackTrace();
                        }
                        System.out.println("T2: After await()");
                  }
            };

            Thread t1 = new Thread(r1, "T1");
            Thread t2 = new Thread(r2, "T2");
           
            t1.start();
            t2.start();
            System.out.println("Done!");
      }

}

Saturday, February 9, 2013

Potential perf issues with String.substring()

This post is relevant for Oracle’s java implementation of 1.6!

Following is the implementation of substring method in String class:

    public String substring(int beginIndex, int endIndex) {
      if (beginIndex < 0) {
          throw new StringIndexOutOfBoundsException(beginIndex);
      }
      if (endIndex > count) {
          throw new StringIndexOutOfBoundsException(endIndex);
      }
      if (beginIndex > endIndex) {
          throw new StringIndexOutOfBoundsException(endIndex - beginIndex);
      }
      return ((beginIndex == 0) && (endIndex == count)) ? this :
          new String(offset + beginIndex, endIndex - beginIndex, value);
    }

Now, if you take a look at the highlighted part of the code, it says a new String is created with same char sequence (‘value’), but with different offset!
Let’s take a scenario where we have a huge string, say of 100MB and we take a substring containing last 100 chars of that string.

String s100MB = <100MB String>; //memory occupied is 100MB
String substring = s100MB.subString(s100MB.length() – 100); //does not occupy any additional memory for the chars of substring as it uses the same char array as the parent string
s100MB = null; //‘substring’ still occupies 100MB of memory where as what it requires is only 200k (for 100 chars)

Now, in real world this may not be a very serious issue as GC is not as instantaneous but cases where ‘substring’ hangs around in memory for very long time – this can be unnecessary wastage of memory! (Worse…. think of the original string being 1GB instead of 100MB!)

<![if !supportLists]>-          <![endif]>Sarang



Thursday, January 31, 2013

final Collection in java

An interesting aspect about final Collection that many java developers may not be familiar with is that making a collection final means only the reference cannot be changed but you can add, remove or change an object inside collection.

 

Example:

            private final List<String> names = new ArrayList<String>();

            names.add("Name1"); //Allowed

            names.add("Name2"); //Allowed

                       

            names = new ArrayList<String>(); //Error

 

Friday, December 28, 2012

Setup yum repository from a linux iso shared on remote windows machine

1. Mount remote windows share on linux system

In general, a useful stuff – specially when important software-installers are stored on a windows share. It can be useful to mount the windows share on your linux system to use it efficiently.

Following are the steps:
  • Login to Linux as root user
  • > mkdir /mtn/winshare 
  • > mount -t cifs //<windows-machine-IP-addr>/<folder-path/ -o username=<user>,password=<pw> /mnt/winshare (For RHEL > 4)
  • > mount -t smbfs //<windows-machine-IP-addr>/<folder-path/ -o username=<user>,password=<pw> /mnt/winshare (For RHEL < 4)

2. Extract Files from iso image and create yum repository

  • > mkdir -p /mnt/iso/{1,2,3}
  • > mount -o loop /mnt/winshare/disk.iso /mnt/iso/1
  • > rpm -ivh  /mnt/iso/1/Packages/<createrepo-package-name>.rpm
  • > cd /mnt/iso
  • > createrepo .
  • > yum clean all

3. Create yum repository configuration file

  • > vi /etc/yum.repos.d/iso.repo
  • Place following text in iso.repo
           [iso] 
           name=My ISO Repo
           baseurl=file:///mnt/iso
           enabled=1
           gpgcheck=0 

Now you should be able to install any package from iso using yum.

- Sarang Anajwala

Monday, December 24, 2012

Debug class-not-found exception

Print ClassNotFoundException

A simple problem that I have found many people struggling with – how to print class-path. Following is the line that can be used to print classpath.

Arrays.toString((((URLClassLoader) Test.class.getClassLoader().getURLs()));

This code returns an array list of all jars and directories on the classpath of the classloader.

-          Sarang Anajwala

 

Friday, December 14, 2012

End of Public Updates for Java SE 6

A quick update on future of Java 6.

From oracle blog -
“The last publicly available release of Oracle JDK 6 is to be released in February, 2013. This means that after 19 February 2013, all new security updates, patches and fixes for Java SE 6 and Java SE 5 will only be available through My Oracle Support and will thus require a commercial license with Oracle.“


Presents a case for upgrade to Java 7!

- Sarang Anajwala

Tuesday, December 11, 2012

Log4j 2.0 - Some important features


Log4j’s latest 2.0 version has been recently released. Following are few of the important and very useful features of Log4j-2.0:

1.       Supports parameter substitution (same as slf4j)
For example:
   LOGGER.info (“User Id is { } and User Email is { }”, userId, userEmail);

2.       Flow Tracing:
To print the entry and exit of a method.
Example:
  public String getUserEmail(int userId) {
    logger.entry(userId);
    User user = UserDao.getUser(userId)
    String email = user.getEmail();
    return logger.exit(email);
  }
  This method will log following messages:
    19:08:07.061 TRACE com.class.MyClass 10 getUserEmail -  entry parms(1)
    19:08:07.061 TRACE com.class.MyClass 13 getUserEmail -  exit with (User.Email@gmail.com)
 
3.       Markers:
To log some special messages.
For example:
 public class MyApp {
 
   private Logger logger = LogManager.getLogger(MyApp.class.getName());
   private static final Marker QUERY_MARKER = MarkerManager.getMarker("SQL");
               
   public String doQuery(String table) {
     logger.entry(param);
     logger.debug(QUERY_MARKER, "SELECT * FROM {}", table);
     return logger.exit();
   }
} 
 
4.       Messages:
Very useful to standardize the format of an application’s log messages.
Example:
            logger.info("User {} has logged in using id {}", username, userId);        
      The above log message can be standardized by implementing a class ‘LoggedInMessage’ implementing ‘Message’ interface.
            logger.info(new LoggedInMessage(userName, userId)); 
                    (‘getFormattedMessage’ method of ‘Message’ interface is used to log the message string.)
        
Some more important types of messages are ThreadDumpMessage, TimestampMessage, MapMessage and few more.
 
5.       Plug-ins:
Log4j 2 uses a Plugin system that makes it extremely easy to extend the framework by adding new Appenders, Filters, Layouts, Lookups, and Pattern Converters without requiring any changes to Log4j.           


-          Sarang Anajwala      

Friday, November 23, 2012

git - tips

  • git remote –v                    
o   Shows remote branches

  • git remote add <remote branch name> <remote branch url>
o   Add a new remote branch

  • git push <remote branch name> <local branch name>
o   push changes from local branch to remote branch

Ref:

Thursday, November 22, 2012

Maven - include a lib manually in local repo

Use following command to include a lib manually in local maven repository:

 

mvn install:install-file -Dfile=./EWSJavaAPIWithJars_1.2.0.jar -DgroupId=local.disk -DartifactId=EWSJavaAPI -Dversion=1.2 -Dpackaging=jar