2011-12-07 9 views
2

私は、ThreadLocalメンバーが実際に異なるスレッドで異なるかどうかを検証しようとしています。ThreadLocalメンバー変数のテスト

これは私のオブジェクトが複数のスレッド間で共有されているTestClassです。したがって第一print文は、2を印刷すべき2つ目の方法1.

をプリントアウトする必要があり

package personal; 



import java.util.*; 

import personal.TestClass; 

import java.lang.reflect.Field; 



public class Test2 { 



     private static TestClass testObj; 

     private static Set<Set<String>> testStringSet; 

     private static Set<Set<Integer>> testIntegerSet; 



     static { 

       testObj = new TestClass(); 

       testStringSet = new HashSet<Set<String>>(); 

       testIntegerSet = new HashSet<Set<Integer>>(); 

     } 



     private static void addToStringSet(Set<String> sets) { 

       synchronized(testStringSet) { 

         testStringSet.add(sets); 

       } 

     } 



     private static void addToIntegerSet(Set<Integer> sets) { 

       synchronized(testIntegerSet) { 

         testIntegerSet.add(sets); 

       } 

     } 



     private static int getTestIntegerSetSize() { 

       synchronized(testIntegerSet) { 

         return testIntegerSet.size(); 

       } 

     } 



     private static int getTestStringSetSize() { 

       synchronized(testStringSet) { 

         return testStringSet.size(); 

       } 

     } 



     private static class MyRunnable implements Runnable { 

       private TestClass tc; 

       private String name; 

       public MyRunnable(TestClass tc, int i) { 

         this.name = "Thread:- " + Integer.toString(i); 

         this.tc = tc; 

       } 

       @Override 

       public void run() { 

         try { 

           Field f1 = tc.getClass().getDeclaredField("setS"); 

           Field f2 = tc.getClass().getDeclaredField("setI"); 

           f1.setAccessible(true); 

           f2.setAccessible(true); 

           Set<String> v1 = (Set<String>)(((ThreadLocal<Set<String>>)(f1.get(tc))).get()); 

           Set<Integer> v2 = (Set<Integer>) f2.get(tc); 

           addToIntegerSet(v2); 

           addToStringSet(v1); 

         } catch (Exception exp) { 

           System.out.println(exp); 

         } 

       } 

     } 



     public static void main(String[] args) { 

       for (int i=1; i<=2; i++) { 

         (new Thread (new MyRunnable(testObj,i))).start(); 

       } 

       try { 

         Thread.sleep(5);      

       } catch (Exception exp) { 

         System.out.println(exp); 

       } 

       System.out.println(getTestStringSetSize()); 

       System.out.println(getTestIntegerSetSize()); 

     } 



} 

- :以下は、私はこれをテストするために使用するクラスです

public class TestClass { 

    private static Set<Integer> setI; 

    private static ThreadLocal<Set<String>> setS; 



    public TestClass() { 

      Set<String> temp = new HashSet<String>(); 

      for (int i=0; i<=4; i++) { 

        setI.add(i); 

        temp.add(Integer.toString(i)); 

      } 

      setS.set(temp); 

    } 


    static { 

      setI = new HashSet<Integer>(); 

      setS = new ThreadLocal<Set<String>>() { 

        protected Set<String> initialValue() { 

          return new HashSet<String>(); 

        } 

      }; 

    } 



    public static void addToIntegerSet(int i) { 

      synchronized(setI) { 

        setI.add(i); 

      } 

    } 



    public static void addToStringSet(String str) { 

      Set<String> sets = setS.get(); 

      sets.add(str); 

      setS.set(sets); 

    } 

} 

1枚目のプリントステートメントも1をプリントアウトします。

何が問題なのですか?

答えて

1

テストクラスでは、はるかに簡単なものから始めます。 ThreadLocalにStringや何かを格納しておき、リフレクションコール(setAccessibleなど)を避けてください。あなたの問題は、この余分なコードのすべてにある可能性が高く、ThreadLocal自体に起因するものではありません。

+0

ありがとうございました。それが助けになった。 – user1084874

関連する問題