6

を減らすんも絶賛の本JCIPはThreadLocalの使用方法については、これを言う:どのようにThreadLocalの使用量は再利用

グローバル変数を使用するためのライセンスとして、またはの手段として、そのスレッド閉じ込めプロパティを処理することにより、ThreadLocalのを乱用するのは簡単です「隠された」メソッド引数を作成します。 スレッドローカル変数は、再利用性を損なう可能性があり、クラス間に隠れた結合を導入する可能性があるため、注意して使用する必要があります。

スレッドローカル変数は再利用性を低下させ、クラス間に隠れた結合を導入する可能性があるとはどういう意味ですか?

+0

簡単なコード例で私の答えを編集しました。 – Tudor

答えて

10

メソッドの計算がメソッドの外部でパラメータに渡されない状態(たとえばクラスフィールドなど)に依存する場合、メソッドの再利用性は低くなりますが、これは、それが存在するオブジェクト/クラスの状態(または悪い場合は、完全に別のクラス)に密接に結びついているからです。

を編集してください。[OK]をクリックすると、これが明確になります。私は質問のためだけにThreadLocalを使用しましたが、一般的にグローバル変数に適用されます。最初のN個の整数の和を複数のスレッドで並列に計算したいとします。それを行う最善の方法は、各スレッドのローカル合計を計算することで、最後にそれらを合計することです。コードが正常に動作し、私たちの期待値を与える

class Foo { 
    public static ThreadLocal<Long> localSum = new ThreadLocal<Long>() { 
     public Long initialValue() { 
      return new Long(0);   
     } 
    }; 
} 

class Task implements Callable<Long> { 

    private int start = 0; 
    private int end = 0;  

    public Task(int start, int end) { 
     this.start = start; 
     this.end = end; 
    } 

    public Long call() { 
     for(int i = start; i < end; i++) { 
      Foo.localSum.set(Foo.localSum.get() + i); 
     } 
     return Foo.localSum.get(); 
    } 
} 

:何らかの理由で、私たちは、各Taskcall方法は、グローバル(静的)変数として別のクラスで定義されているThreadLocal sum変数を使用することを決定しますグローバルな合計ですが、Taskクラスとそのcallメソッドは、現在Fooクラスに厳密に結合されています。別のプロジェクトでTaskクラスを再利用する場合は、Fooクラスも移動する必要があります。そうしないと、コードはコンパイルされません。

これは単純な例ですが、「隠された」グローバル変数の危険性を確認することができます。また、コードを読み取っている誰かがクラスFooを検索し、Foo.localSumの定義が何であるかを見なければならないので、読みやすさにも影響します。クラスはできるだけ自己完結型にする必要があります。

+0

@Subhra - チューダーの答えは十分明確ではありませんか?なぜ具体的に「サンプルコード」が必要なのですか? –

+0

@Subhra:簡単なコード例で編集しました。 – Tudor

3

ThreadLocalはスレッドごとに宣言されます。通常、フィールドはそのクラスのオブジェクトごとに宣言されます。ThreadLocalが誤用されると、多くのことが起こる可能性があります。

スレッドが複数のオブジェクト(単一クラスまたは複数クラスのいずれか)を通過する場合、このスレッドで使用されるThreadLocalは、これらすべてのインスタンスにわたって同じインスタンスです。これはBGが話しているカップリングです。カップリングがある瞬間、再利用は困難になり、エラーが発生しやすくなります。

+0

ThreadLocalに関するJavaの文書によれば、通常、ThreadLocalsはプライベート静的であるべきですが、 'static'はThreadLocalによって強制されません。したがって、技術的にはThreadLocalはスレッドごとにインスタンスごとに実行できます。しかし、あなたの2番目のパラグラフは質問にかなりよく答えます。 – Inquisitive

関連する問題