2017-12-28 25 views
-1

私はThreadLocalオブジェクトの使用をJavaでテストしたいのですが、私のinitialValue()は動作していないようです。そして、実際にはget()set()の前に呼び出すと、変数IDが期待通りに100を返します。ここに私のコードは次のとおりです。なぜThreadLocalのinitialValue()が機能しないのですか?

public class UsageThreadLocal implements Runnable { 
    private AnotherThreadID<Long> var; 

    public UsageThreadLocal(AnotherThreadID<Long> v) { 
     this.var = v; 
    } 

    public void run() { 
     try { 
      print("var getThreadID =" + var.get()); 
      Thread.sleep(200); 
      var.set(Thread.currentThread().getId()); 
      print("var getThreadID =" + var.get()); 
     } catch (InterruptedException x) { 
     } 
    } 

    private static void print(String msg) { 
     String name = Thread.currentThread().getName(); 
     System.out.println(name + ": " + msg); 
    } 

    public static void main(String[] args) { 
     AnotherThreadID<Long> tid = new AnotherThreadID<Long>() { 
      @Override 
      public Long initialValue() { 
       ID = new Long(100); 
       System.out.println("I'm in initialValue()!"); 
       return ID; 
      } 
     }; 
     UsageThreadLocal shared = new UsageThreadLocal(tid); 

     try { 
      Thread threadA = new Thread(shared, "threadA"); 
      threadA.start(); 

      Thread.sleep(50); 

      Thread threadB = new Thread(shared, "threadB"); 
      threadB.start(); 

      Thread.sleep(50); 

      Thread threadC = new Thread(shared, "threadC"); 
      threadC.start(); 
     } catch (InterruptedException x) { 
     } 
    } 
} 

class AnotherThreadID<T> extends ThreadLocal<T> { 
    public T ID; 

    @Override 
    public void set(T newID) { 
     ID = newID; 
    } 

    @Override 
    public T get() { 
     return ID; 
    } 

} 

と私のコードの結果を実行する:

threadA: var getThreadID =null 
threadB: var getThreadID =null 
threadC: var getThreadID =null 
threadA: var getThreadID =9 
threadB: var getThreadID =10 
threadC: var getThreadID =11 

私のコードまたはIの問題はThreadLocalの使用状況を誤解していますか?

+0

すべてのオブジェクトは自動的に 'Object'を継承し、それを明示的に拡張する必要はありません(' extends Object') –

答えて

1

問題はAnotherThreadIDの実装にあります。 ThreadLocalは、各スレッドの値を保持することです。get()set()は、基本的にはThreadLocalになりません。

AnotherThreadIDクラスを削除して、AnotherThreadIDThreadLocalと置き換えると、コードをそれ以上変更する必要はありません。

+0

Thanks @ Kevin Wang。つまり、 '' get() ''や '' set() ''をオーバーライドするのはもっと複雑な作業が必要なのでしょうか? – zhanghui

+0

@zhanghui通常、 'initialValue()'を実装すれば十分です。そして、あなたがThreadLocalのget()とset()を見れば、それがうまくいく方法がわかります。正直なところ、私はどのような場合にそれらを無効にする必要があるかわかりません。 –

+0

これは、 '' MyThreadLocal''オブジェクトに必要な動作をビルドするための基本的な方法として '' get() ''や '' set() ''を使うべきですか? – zhanghui

0

AnotherThreadIDは、そのスレッドによって初期化されるはずですが、メインスレッドで初期化する必要があります。 AnotherThreadIDインスタンスは1つしかありません。実際、各スレッドにはインスタンスが必要です。

関連する問題