Java-ThreadLocalクラス

5224 ワード

一、ThreadLocalを導入する
/*  ThreadLocal  
 * 	 ThreadLocal:               。
 * 			                          (      get   set       ) 。 
 *                               。                ,
 *           。             ,             ,                   。
 *                        ,           。

 ThreadLocal                  ,          。 
 JDK1.5   ThreadLocal       ,   ThreadLocal,      T           。
      ThreadLocal   get   set           T 。 ThreadLocal        ,
                      T             。            Threadlocal 
           public   ,   get()   set ()     。

          inintValue()   protected   。           。

    :      initValue(),    null 。        set   ,      get    ,
 get          initValue     。            ,     get      null 。
         set          。                          get        set ,
       initValue     ,         。 

 * */

       テスト、ThreadLocalがない場合:
public class TestThreadLocal {
	public static int a = 0;
	

	public static void main(String[] args) {
		MyThread myThread=new MyThread();
		myThread.start();
		for(int i=0;i<5;i++){
			
			
			System.out.println(Thread.currentThread().getName()+":"+a);
			
		}
	}

	

	public static class MyThread extends Thread {
		public void run(){
			for(int i=0;i<5;i++){
				a=++a;
				
				System.out.println(Thread.currentThread().getName()+":"+a);
				
			}
		}
	}

}

  テスト結果:
main:1
main:2
main:3
main:4
main:5
Thread-0:6
Thread-0:7
Thread-0:8
Thread-0:9
Thread-0:10

   結果は混乱し,2つのスレッドの実行は明らかに交差していることが分かった.
   ThreadLocalを使用した後:
public class TestThreadLocal {
	//public static int a = 0;
	public static ThreadLocal a=new ThreadLocal(){
		public Integer initialValue(){//   a  
			return 0;
		}
	};

	public static void main(String[] args) {
		MyThread myThread=new MyThread();
		myThread.start();
		for(int i=0;i<5;i++){
			//a=++a;
			a.set(a.get()+1);
			System.out.println(Thread.currentThread().getName()+":"+a.get());
			
		}
	}

	

	public static class MyThread extends Thread {
		public void run(){
			for(int i=0;i<5;i++){
				//a=++a;
				a.set(a.get()+1);
				System.out.println(Thread.currentThread().getName()+":"+a.get());
				
			}
		}
	}

}

結果:
Thread-0:1
Thread-0:2
Thread-0:3
Thread-0:4
Thread-0:5
main:1
main:2
main:3
main:4
main:5

  スレッドローカル変数を使用した後、getメソッドとsetメソッドで変数を読み書きする必要があります.
二、簡単にThreadLocalを紹介する
     
           
 /**
     * Returns the current thread's "initial value" for this
     * thread-local variable.  This method will be invoked the first
     * time a thread accesses the variable with the {@link #get}
     * method, unless the thread previously invoked the {@link #set}
     * method, in which case the initialValue method will not
     * be invoked for the thread.  Normally, this method is invoked at
     * most once per thread, but it may be invoked again in case of
     * subsequent invocations of {@link #remove} followed by {@link #get}.
     *
     * 

This implementation simply returns null; if the * programmer desires thread-local variables to have an initial * value other than null, ThreadLocal must be * subclassed, and this method overridden. Typically, an * anonymous inner class will be used. * * @return the initial value for this thread-local */ protected T initialValue() { return null; }


    
        変数の初期化操作はここで完了し、デフォルトはnullを返し、overrideという方法を提案し、getの前にset操作が行われていることを確認し、getの時にエラーが発生しないようにします.
   
 public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null)
                return (T)e.value;
        }
        return setInitialValue();
    }

      ThreadLocalクラスには、keyを現在のthreadLocalとするobjectが格納された内部静的クラスThreadLocalMapがある.
 public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

     setメソッドも で、ThreadLocalに っている は この2つのメソッドで されます.ああ、removeもあります.
 
 public void remove() {
         ThreadLocalMap m = getMap(Thread.currentThread());
         if (m != null)
             m.remove(this);
     }

   コード... まず て、それから たちのspringソースの に り えて、これはただのエピソードです.