7

Java Concurrency in practice Chapter 3.3.3より。スレッドローカル

スレッドローカル変数は、変更可能なシングルトンまたはグローバル変数に基づく設計での共有を防ぐためによく使用されます。

変更可能なシングルトンの男を ThreadLocal でラップすると、各スレッドはシングルトンの独自のコピーを持ちますか? それでは、どのようにしてシングルトンのままになりますか?これは著者が意図したことですか、それともここでかなり明白な何かが欠けていますか?

4

3 に答える 3

2

可変シングルトンの男をThreadLocalでラップすると

シングルトンクラスをThreadLocalでラップするのではなく、シングルトン内に含まれるオブジェクトで、変更可能またはスレッドセーフではありません。例で正しく説明されているように、JDBC接続はスレッドセーフではなく、追加の保護が必要になるため、競合が増加します。

したがって、共有の目的でシングルトンを使用する場合は、すべてのスレッドに独自の接続があり、保護を追加する必要がないため、それらをThreadLocalに置き換えることをお勧めします。

ThreadLocalのユースケースの他の良い例は、ランダム生成です。単一のRandomオブジェクトがある場合、「シード」のスレッド内で競合が発生するため、各スレッドに独自のRandomオブジェクトがある場合、競合は発生しなくなります。これは理にかなっています。 。

于 2013-02-09T10:09:12.720 に答える
0

シングルトンを(デザインパターンとして)ThreadLocalでラップすると、シングルトンのままになります。ThreadLocalには大きな魔法はありません。スレッドローカルのソースを確認すると、見たばかりです。マップを使用し、現在のスレッドをキーとして使用します。したがって、シングルトン(適切に実装されたもの)をThreadLocalに配置することはまったく役に立ちません。さまざまな方法で同じシングルトンを取得するだけです。

作成者は、シングルトンやグローバル変数を多用する設計の場合、スレッドごとに一意のものが必要で、呼び出し階層の最後まで渡したくない場合は、ThreadLocalが適切な選択だと思います。しかし、これはシングルトンとは異なります。もちろん、ThreadLocalをシングルトンにカプセル化して、スレッド固有の状態にすることができます(ただし、シングルトンはもう呼び出しません)。

于 2013-02-09T10:08:08.343 に答える
0

この行で私が理解したのは、Singleton クラスが多くのスレッドによって読み書きされる可変状態を持つようにアプリケーションが設計されている場合、スレッド セーフが必要になるため、その状態へのすべてのアクセスをシリアル化する必要があるということです。その変更可能なシングルトンに ThreadLocal を作成することを検討してください。(本から :-) たとえば、シングルスレッド アプリケーションは、すべてのメソッドに Connection を渡す必要がないように、起動時に初期化されるグローバル データベース接続を維持する場合があります。JDBC 接続はスレッド セーフではない可能性があるため、追加の調整なしでグローバル接続を使用するマルチスレッド アプリケーションもスレッド セーフではありません。リスト 3.10 の ConnectionHolder のように、ThreadLocal を使用して JDBC 接続を格納すると、各スレッドは独自の接続を持つようになります。

private static ThreadLocal<Connection> connectionHolder= new ThreadLocal<Connection>() {
      public Connection initialValue() {
  return DriverManager.getConnection(DB_URL);
  }
 };
   public static Connection getConnection() {
     return connectionHolder.get();
     }
于 2013-02-09T10:51:26.923 に答える