Java ThreadLocal は、アクセスする各スレッドに独自の独立して初期化された変数のコピーを提供する特別なタイプの変数です。これは、各スレッドが独自のバージョンの変数を必要とするマルチスレッド環境で特に役立ちます。
ThreadLocal は、スレッドローカル変数を提供する Java のクラスです。このような変数に (get メソッドまたは set メソッド経由で) アクセスする各スレッドは、変数の独自の独立したコピーを持ちます。 ThreadLocal インスタンスは通常、状態をスレッドに関連付けたいクラスのプライベート静的フィールドです。
スレッドが ThreadLocal 変数に初めてアクセスすると、ThreadLocal インスタンスはそのスレッドの変数の新しいコピーを作成します。このコピーはスレッド自身のメモリに保存され、他のスレッドがアクセスできないようにします。内部的には、ThreadLocal は、キーがスレッド参照であり、値が対応するスレッドローカル値であるマップを維持します。
ThreadLocal は、変数が複数のスレッドから同時にアクセスされないように分離する必要がある場合に最適です。これは、ユーザー セッションの追跡、データベース接続、スレッド間で共有すべきではないその他のリソースなど、各スレッドが独自のバージョンの変数を持つ必要があるシナリオでよく使用されます。
ThreadLocal を使用してスレッド固有のカウンターを維持する簡単な例を考えてみましょう。
public class ThreadLocalExample { private static ThreadLocal<Integer> threadLocalCounter = ThreadLocal.withInitial(() -> 0); public static void main(String[] args) { Runnable task = () -> { for (int i = 0; i < 5; i++) { threadLocalCounter.set(threadLocalCounter.get() + 1); System.out.println(Thread.currentThread().getName() + " - Counter: " + threadLocalCounter.get()); } }; Thread thread1 = new Thread(task, "Thread-1"); Thread thread2 = new Thread(task, "Thread-2"); thread1.start(); thread2.start(); } }
上記のコードを実行すると、各スレッドが独自のカウンターを独立してインクリメントしていることがわかります。
Thread-1 - Counter: 1 Thread-1 - Counter: 2 Thread-1 - Counter: 3 Thread-1 - Counter: 4 Thread-1 - Counter: 5 Thread-2 - Counter: 1 Thread-2 - Counter: 2 Thread-2 - Counter: 3 Thread-2 - Counter: 4 Thread-2 - Counter: 5
これは、各スレッドが他のスレッドから分離された独自のカウンターのコピーを持っていることを示しています。
ThreadLocal は単純なカウンターのためだけのものではありません。スレッドの安全性が最優先される、より複雑なシナリオに強力なアプリケーションを提供します。
Web アプリケーションでは、ThreadLocal は、スレッド間で共有すべきではないユーザー セッション情報やデータベース接続を保持するためによく使用されます。例:
public class ThreadLocalExample { private static ThreadLocal<Integer> threadLocalCounter = ThreadLocal.withInitial(() -> 0); public static void main(String[] args) { Runnable task = () -> { for (int i = 0; i < 5; i++) { threadLocalCounter.set(threadLocalCounter.get() + 1); System.out.println(Thread.currentThread().getName() + " - Counter: " + threadLocalCounter.get()); } }; Thread thread1 = new Thread(task, "Thread-1"); Thread thread2 = new Thread(task, "Thread-2"); thread1.start(); thread2.start(); } }
このシナリオでは、ユーザー リクエストを処理する各スレッドが独自の User オブジェクトを持ち、あるユーザーのデータが別のユーザーのリクエストによってアクセスされるのを防ぎます。
ThreadLocal は強力ですが、リスクがないわけではありません。よくある落とし穴の 1 つは、スレッド ローカル変数のクリーンアップを忘れることです。これにより、特に長時間実行されるアプリケーションでメモリ リークが発生する可能性があります。
これを防ぐには、スレッドローカル値が必要なくなったら、常に remove メソッドを使用します。
Thread-1 - Counter: 1 Thread-1 - Counter: 2 Thread-1 - Counter: 3 Thread-1 - Counter: 4 Thread-1 - Counter: 5 Thread-2 - Counter: 1 Thread-2 - Counter: 2 Thread-2 - Counter: 3 Thread-2 - Counter: 4 Thread-2 - Counter: 5
ThreadLocal を使用してデータベース接続を管理する方法の例を次に示します。
public class UserContext { private static ThreadLocal<User> currentUser = new ThreadLocal<>(); public static void set(User user) { currentUser.set(user); } public static User get() { return currentUser.get(); } public static void clear() { currentUser.remove(); } }
各スレッドは独自のデータベース接続を持ち、スレッド間のアクセスの問題を防ぎます。
Java の ThreadLocal は、マルチスレッド環境でスレッドローカル変数を管理するための強力なツールです。各スレッドに変数の独自の独立したコピーを提供することで、スレッドの安全性を確保します。ただし、大きな力には大きな責任が伴います。メモリ リークを避けるために、ThreadLocal 変数を常にクリーンアップすることを忘れないでください。
ThreadLocal の効果的な使用方法についてご質問がある場合、または使用中に問題が発生した場合は、お気軽に以下にコメントしてください。
で投稿の詳細をお読みください: Java スレッド ローカルはどのように機能しますか?安全なスレッドローカル変数の背後にある秘密を明らかにする
以上がJava スレッド ローカルはどのように機能しますか?安全なスレッドローカル変数の背後にある秘密を明らかにするの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。