2011-09-13 9 views
7

Javaと並行性に関する質問があります。Javaキャッシュされたスレッドプールとスレッドローカル

たとえば、aというThreadLocal変数があります。私はCachedThreadPoolを使って新しいスレッドを取得します。 スレッドが再利用されると、ThreadLocal変数はどうなりますか?それは同じ値を持ちます(同じスレッドであるため)、または空になります(スレッドが新しい場合のように)。スレッドがプールに戻された場合

おかげ

答えて

10

デフォルトでは、スレッドルーカルはスレッドと共に再利用されます。あなたが再初期化されるためにそれらを必要とする場合は、以下に記載する方法をオーバーライドすることによってそれを行うことができます。

from javadoc for java.util.concurrent.ThreadPoolExecutor

フックメソッド このクラスには、オーバーライドbeforeExecute(java.lang.Threadの、Javaの保護提供します。 lang.Runnable)およびafterExecute(java.lang.Runnable、java.lang.Throwable)メソッドを使用して、各タスクの実行前後で呼び出されます。これらは、実行環境を操作するために使用できます。 ThreadLocalsの再初期化、統計の収集、またはログエントリの追加などです。さらに、メソッドterminated()をオーバーライドして、エグゼキュータが完全に終了した後に実行する必要がある特別な処理を実行できます。 フックまたはコールバックメソッドが例外をスローすると、内部ワーカースレッドが失敗し、突然終了することがあります。

+1

問題を解決する私は、ThreadPoolExecutorがスレッドのローカルを認識する必要があることをここに見ています。悪い分離の種類。スレッドが実行を終了すると、イベントをスローするオブザーバブルによって解決できます。特定のスレッドローカルは、afterExecuteイベントが発生するとクリーンアップを行います(オブザーバ)。 –

3

は、ThreadLocal変数はまだそれに添付されます。プールでThreadLocalsを使用する場合は、スレッドがプールから取得され、返される前に設定を解除できるように注意する必要があります。

2

スレッドのスレッドローカルプールは、リフレクションを使用してクリアできます。あなたが行うことができます

public static void clearAllThreadLocals() { 
    try { 
     Field threadLocals = Thread.class.getDeclaredField("threadLocals"); 
     threadLocals.setAccessible(true); 
     threadLocals.set(Thread.currentThread(), null); 
    } catch (Exception e) { 
     throw new AssertionError(e); 
    } 
} 
関連する問題