题目:请用程序解析ThreadLocal原理,并用程序展示其作用。
 
答:
/**
*    
*/

package mythread;

import java.util.Collections;
import java.util.Map;
import java.util.HashMap;
import java.util.Random;

/**
* Those code show you muti threads use thread local to keep his own variable or object,    
* and make sure his variable keep the same all the time!
* @author daniel zhou
*
*/

public class MyThreadLocal {

   /**
    * Main Enter
    * @param args
    */

   public static void main(String[] args) {
    ThreadTest tt= new ThreadTest();
    Thread t1= new Thread(tt, "thread 1");
    Thread t2= new Thread(tt, "thread 2");
    Thread t3= new Thread(tt, "thread 3");
    t1.setPriority(Thread.MAX_PRIORITY);
    t1.start();
    t2.start();
    t3.start();
  }
}

/**
* This thread have use thread local implements MyThreadLocalImpl
*    to keep mutil thread's variable, this is a key
* @author daniel zhou
*
*/

class ThreadTest implements Runnable{

   private static MyThreadLocalImpl threadlocal= new MyThreadLocalImpl();
    
  @Override
   public void run() {
    String currentThread=Thread.currentThread().getName();
    System.out.println(currentThread+ " runing");
    VO vo = getVO();
    Random random = new Random();
         int age = random.nextInt(100);
    String value=String.valueOf(age);
    vo.setAge(value);
    System.out.println(currentThread+ "set age: "+vo.getAge());
    System.out.println(currentThread+ " first time get age: "+vo.getAge());
     try {
      Thread.sleep(2000);
    } catch (InterruptedException e) {
       // TODO Auto-generated catch block
      e.printStackTrace();
    }
    System.out.println(currentThread+ " second get age: "+vo.getAge());
     try {
      Thread.sleep(2000);
    } catch (InterruptedException e) {
       // TODO Auto-generated catch block
      e.printStackTrace();
    }
    System.out.println(currentThread+ " third get age: "+vo.getAge());
     //clear up
    clearVO();
  }
    
   /**
    * Get object from threadlocal
    * @return
    */

   public static VO getVO(){
    VO vo= (VO) threadlocal.get();    
     if (vo== null) {
      vo= new VO();        
      threadlocal.set(vo);
    }
     return vo;
  }

   /**
    * Clear up threadlocal
    */

   public static void clearVO(){
    VO vo= (VO) threadlocal.get();
    threadlocal.set( null);
    
     if (vo!= null) {
      vo= null;
    }
  }
    
}

/**
* Here I have use java.util.Map, java.util.Collections to implements an simple threadlocal Object
* @author daniel zhou
*
*/

class MyThreadLocalImpl{
    
   private Map<Thread, Object> valueMap=Collections.synchronizedMap( new HashMap<Thread, Object>());
    
   public void set(Object newValue){
    valueMap.put(Thread.currentThread(), newValue);
  }
    
   public Object get(){
    Thread curThread=Thread.currentThread();
    Object obj=valueMap.get(curThread);
     if (obj== null && !valueMap.containsKey(curThread)) {
      obj=initialValue();
      valueMap.put(curThread, obj);
    }
     return obj;
  }
    
   public Object initialValue(){
     return null;
  }
}

/**
* VO, demo object
* @author daniel zhou
*
*/

class VO{
    
   private String age;
    
   public void setAge(String age){
     this.age=age;
  }
    
   public String getAge(){
     return age;
  }
    
}