2011年1月7日金曜日

JavaでThreadLocalを使ってみる

マルチスレッドプログラムにおいて、スレッド毎にpublic staticな変数を作りたい場合
というのがたまにあります。

そんなときに使うのがThreadLocalというクラス。

これを利用すると、スレッド単位でグローバルな変数と言うのを定義できます。

下記がサンプルコード。
スレッド毎に、KeyがIntegerでValueがStringのHashMapを返ししている
様を確認できるサンプルプログラムです。

=====================================

import java.util.HashMap;
import java.util.Map;


public class ThreadLocalTest {
  private static class ThreadHashMap{

      private static ThreadLocal<HashMap<Integer,String>> tl = new ThreadLocal<HashMap<Integer,String>>() {
          protected synchronized HashMap<Integer,String> initialValue() {
              return new HashMap<Integer,String>();
          }
      };

      public static HashMap<Integer,String> get() {
          return tl.get();
      }
  }
  private static class TestThread extends Thread{
   public void run() {
    try {
     for(int i=0;i<5;i++){
      Map<Integer,String> map=ThreadHashMap.get();
      map.put(i, getName());
      sleep(5);
     }
     System.out.println(getName()+":"+ThreadHashMap.get());;
    } catch (Exception e) {
     e.printStackTrace();
    }
   }   
  }
  public static void main(String[] args) throws InterruptedException{
   Thread th=new TestThread();
   Thread th2=new TestThread();
   th.start();
   th2.start();
   
   while(Thread.activeCount()!=1){
    System.out.println("WAIT"+Thread.activeCount());
    Thread.sleep(100);
   }
   System.out.println("END!!!");
  } 
}