Tuesday, January 31, 2012

ThreadLocal - Usage and Explanation

Refer to a developer article : http://java.dzone.com/articles/java-thread-local-%E2%80%93-how-use

Read documentation on usage first in the above link. Then refer to the following sample code from the developer:


01.package com.veerasundar;
02. 
03.public class Context {
04. 
05.  private String transactionId = null;
06. 
07.        /* getters and setters here */
08. 
09.}
 
01.package com.veerasundar;
02. 
03./**
04. * this class acts as a container to our thread local variables.
05. * @author vsundar
06. *
07. */
08.public class MyThreadLocal {
09. 
10.  public static final ThreadLocal userThreadLocal = new ThreadLocal();
11. 
12.    public static void set(Context user) {
13.      userThreadLocal.set(user);
14.  }
15. 
16.   public static void unset() {
17.        userThreadLocal.remove();
18.   }
19. 
20.   public static Context get() {
21.       return userThreadLocal.get();
22.   }
23.}
 
01.package com.veerasundar;
02. 
03.public class ThreadLocalDemo extends Thread {
04. 
05.   public static void main(String args[]) {
06. 
07.        Thread threadOne = new ThreadLocalDemo();
08.       threadOne.start();
09. 
10.      Thread threadTwo = new ThreadLocalDemo();
11.       threadTwo.start();
12.  }
13. 
14.   @Override
15.   public void run() {
16.     // sample code to simulate transaction id
17.       Context context = new Context();
18.        context.setTransactionId(getName());
19. 
20.        // set the context object in thread local to access it somewhere else
21.       MyThreadLocal.set(context);
22. 
23.     /* note that we are not explicitly passing the transaction id */
24.        new BusinessService().businessMethod();
25.     MyThreadLocal.unset();
26. 
27.  }
28.}
 
01.package com.veerasundar;
02. 
03.public class BusinessService {
04. 
05.  public void businessMethod() {
06.      // get the context from thread local
07.        Context context = MyThreadLocal.get();
08.      System.out.println(context.getTransactionId());
09. }
10.}
 
 

Sunday, January 29, 2012

Program to manipulate dependency map

Java Code :
-------------
package com.test.data;

import java.util.*;

// @author - Lakshman.
public class DependencyMap {
   
    private Map> dataMap = null;
   
    private Map valueMap = new HashMap();
   
    public DependencyMap(Map> argMap) {
        if (argMap != null) {
            dataMap = argMap;
        }
        else {
            dataMap = new HashMap>();
        }
    }
   
    public void createMap(String keyName, String keyVal) {       
        if (!dataMap.containsKey(keyName)) {
            return;
        }
       
        // Check if value is already set in values map.
        if (!valueMap.containsKey(keyName)) {
            valueMap.put(keyName, keyVal);           
        }
       
        // Get dependents.
        ArrayList valList = dataMap.get(keyName);
        if (valList == null) {
            return;
        }

        // Increment the value.
        int val = Integer.parseInt(keyVal);
        val++;
        String depVal = Integer.toString(val);


        // For each dependent, set - value + 1
        for (String depKey : valList) {
            if (!valueMap.containsKey(depKey)) {
                valueMap.put(depKey, new String(depVal));
            }
        }

        // For each dependent, recursively traverse.
        for (String depKey : valList) {
            createMap(depKey, depVal);
        }       
    }
   
    public void displayValueMap() {
        for (Map.Entry valEntry : valueMap.entrySet()) {
            System.out.println("Key = " + valEntry.getKey() + " :: Value = " + valEntry.getValue());
        }
    }
   
    public void displayDataMap() {
        if (dataMap == null) {
            return;
        }
       
        int count = 0;
        for (Map.Entry> dataMapEntry : dataMap.entrySet()) {
            count++;
            System.out.print("Element number - " + count);
            System.out.print (" - Key = " + dataMapEntry.getKey() + " :: Dependenct List = ");
            ArrayList valList = dataMapEntry.getValue();
            if (valList == null) {
                System.out.println();
                continue;
            }
            for (String val : valList) {
                System.out.print(val + " ; ");
            }
            System.out.println();
        }
    }
   
    private static HashMap> populateMap1() {
        HashMap> dataMap = new HashMap>();

        ArrayList valList = new ArrayList();
        valList.add("B");
        valList.add("C");
        valList.add("E");
        dataMap.put("A", valList);
       
        valList = new ArrayList();
        valList.add("C");
        valList.add("D");
        dataMap.put("B", valList);
       
        valList = new ArrayList();
        valList.add("E");
        dataMap.put("C", valList);

        dataMap.put("D", null);
        dataMap.put("E", null);       
       
        return dataMap;
    }
   
    public static void testcase1() {
        Map> dataMap = populateMap1();
        DependencyMap depMap = new DependencyMap(dataMap);
        depMap.displayDataMap();
        depMap.createMap("A", "1");
        depMap.displayValueMap();       
    }
   
    public static void main(String[] args) {
        testcase1();
    }
}

Output
--------
Element number - 1 - Key = D :: Dependenct List =
Element number - 2 - Key = E :: Dependenct List =
Element number - 3 - Key = A :: Dependenct List = B ; C ; E ;
Element number - 4 - Key = B :: Dependenct List = C ; D ;
Element number - 5 - Key = C :: Dependenct List = E ;

Key = D :: Value = 3
Key = E :: Value = 2
Key = A :: Value = 1
Key = B :: Value = 2
Key = C :: Value = 2



Friday, January 27, 2012

Servlets / JSP Tutorials

Servlets 3.0 / JSP 2.2 tutorials - 1: http://courses.coreservlets.com/Course-Materials/csajsp2.html

Thursday, January 26, 2012

Unicode character APIs in Java

package com.struts1.tutorials.utils;

import java.util.ArrayList;
import java.util.List;

public class UnicodeCheck {
   
    public static int countUnicodeCharacters(char[] charArray) {
        if(charArray == null || charArray.length == 0)
            return 0;
        int numUnicodeChars = 0;
        for (int i = 0; i < charArray.length; i++) {
            if (Character.isLetter(charArray[i]) && !((charArray[i] >= 'a') && (charArray[i] <= 'z'))
                    && !((charArray[i] >= 'A') && (charArray[i] <= 'Z'))) {
                numUnicodeChars++;
                System.out.println("Unicode character = " + charArray[i]);
            }           
        }
        return numUnicodeChars;
    }
   

    // This does not work.
    public static int countUnicodeCharacters2(char[] charArray){
        if(charArray == null || charArray.length == 0)
            return 0;
        int numUnicodeChars = 0;
       
        System.out.println("********* Start Testing isLetter() API ************");
        for (int i = 0; i < charArray.length; i++) {
            if (Character.isLetter(charArray[i]) && !Character.isLowerCase(charArray[i]) && !Character.isUpperCase(charArray[i])) {
                numUnicodeChars++;
                System.out.println("isLetter() API : Character is unicode = " + charArray[i]);
                System.out.println("Character = " + charArray[i] +
                        " :: int value = " + i +
                        " :: getType = " + Character.getType(charArray[i]));
            }
        }
        System.out.println("********* End Testing isLetter() API ************");
        System.out.println("isLetter() API: Count of unicode characters = " + numUnicodeChars);
        return numUnicodeChars;
       
    }   
   
    public static void testcase1(char[] chArr) {
        System.out.println("Begin Testcase1()");
        for (char ch : chArr ) {
            int i = ch;
            System.out.println("Character = " + ch +
                                " :: int value = " + i +
                                " :: getType = " + Character.getType(ch));
            Character.UnicodeBlock block = Character.UnicodeBlock.of(ch);
            System.out.println("Unicode block = " + block);
            System.out.println("isUnicodeIdentifierPart = " + Character.isUnicodeIdentifierPart(ch));
            System.out.println("isUnicodeIdentifierStart = " + Character.isUnicodeIdentifierStart(ch));
        }
    }
   
    public static void main(String[] args) {
       
        List pwdList = new ArrayList();       
        pwdList.add("welcome1");
        pwdList.add("Enañol");
        pwdList.add("wel\u00f1");       
        pwdList.add("bargain12345");
        pwdList.add("....12345");
        pwdList.add("change1234");
        pwdList.add("cat12345");
               
        for (String pwd : pwdList) {
            char[] pwdChars = pwd.toCharArray();
            int count = countUnicodeCharacters(pwdChars);           
            System.out.println("Input password = " + pwd + " :: unicode chars count = " + count);
        }
    }
}



Output
=====
Input password = welcome1 :: unicode chars count = 0
Unicode character = ñ
Input password = Enañol :: unicode chars count = 1
Unicode character = ñ
Input password = welñ :: unicode chars count = 1
Input password = bargain12345 :: unicode chars count = 0
Input password = ....12345 :: unicode chars count = 0
Input password = change1234 :: unicode chars count = 0
Input password = cat12345 :: unicode chars count = 0

Wednesday, January 25, 2012

Synchronization Cheat Sheet

Reference : http://www.janeg.ca/scjp/threads/synchronization.html

  • every instance of class Object and its subclass's has a lock
  • primitive data type fields (Scalar fields) can only be locked via their enclosing class
  • fields cannot be marked as synchronized however they can be declared volatile which orders the way they can be used or you can write synchronized accessor methods
  • array objects can be synchronized BUT their elements cannot, nor can their elements be declared volatile
  • Class instances are Objects and can be synchronized via static synchronized methods

Synchronized blocks

  • allow you to execute synchronized code that locks an object without requiring you to invoke a synchronized method
    synchronized( expr ) {
        // 'expr' must evaluate to an Object
    }

Synchronized methods

  • declaring a method as synchronized ie synchronized void f() is equivalent to
    void f() { synchronized(this) {
        // body of method
      } 
    }
  • the synchronized keyword is NOT considered part of a method's signature. IT IS NOT AUTOMATICALLY INHERITED when subclasses override superclass methods
  • methods in Interfaces CANNOT be declared synchronized
  • constructors CANNOT be declared synchronized however they can contain synchronized blocks
  • synchronized methods in subclasses use the same locks as their superclasses
  • synchronization of an Inner Class is independent on it's outer class
  • a non-static inner class method can lock it's containing class by using a synchronized block
    synchronized(OuterClass.this) {
        // body 
    }

Locking

  • locking follows a built-in acquire-release protocol controlled by the synchronized keyword
  • a lock is acquired on entry to a synchronized method or block and released on exit, even if the exit is the result of an exception
  • you cannot forget to release a lock
  • locks operate on a per thread basis, not on a per-invocation basis
  • Java uses re-entrant locks ie a thread cannot lock on itself
class Reentrant {

  public synchronized void a() {
      b();
      System.out.println("here I am, in a()");
  }
  public synchronized void b() {
      System.out.println("here I am, in b()");
  }
}
  • in the above code, the synchronized method a(), when executed, obtains a lock on it's own object. It then calls synchronized method b() which also needs to acquire a lock on it's own object
  • if Java did not allow a thread to reacquire it's own lock method b() would be unable to proceed until method a() completed and released the lock; and method a() would be unable to complete until method b() completed. Result: deadlock
  • as Java does allow reentrant locks, the code compiles and runs without a problem
  • the locking protocol is only followed for synchronized methods, it DOES NOT prevent unsynchronized methods from accessing the object
  • once a thread releases a lock, another thread may acquire it BUT there is no guarantee as to WHICH thread will acquire the lock next

Class fields and methods

  • locking an object does not automatically protect access to static fields
  • protecting static fields requires a synchronized static block or method
  • static synchronized statements obtain a lock on the Class vs an instance of the class
  • a synchronized instance method can obtain a lock on the class
    synchronized(ClassName.class) {
        // body 
    }
  • the static lock on a class is not related to any other class including it's superclasses
  • a lock on a static method has no effect on any instances of that class (JPL pg 185)
  • you cannot effectively protect static fields in a superclass by adding a new static synchronized method in a subclass; an explicit block synchronization is the preferred way
  • nor should you use synchronized(getClass()); this locks the actual Class which might be different from the class in which the static fields are declared

Bitwise operations and samples

Notes-1 : http://leepoint.net/notes-java/data/expressions/bitops.html

Friday, January 6, 2012