2

trueのJavaAppEngineアプリがあります。複数のスレッドが単一のインスタンスで実行され、複数の同時リクエストを処理することを私は知っています。コードはスレッドセーフである必要があること、つまりグローバル静的変数であってはならないことを理解しています。

私が理解していないのは、リクエストが終了したときにスレッドが強制終了されるのか、それとも同じスレッドを使用して別の着信リクエストの処理が完了したらそれを処理できるのかということです。

なぜこれが重要なのですか?いくつかの詳細:

スレッドローカル変数を含む静的クラスがあります。

public abstract class Foo {
    private static final ThreadLocal<Boolean> threadIsApiCall = new ThreadLocal<Boolean>();
    static {
         setIsApiCall(false);
    }
}

この変数は、このスレッドに対する現在のリクエストがREST APIの呼び出しであるか、それとも独自のカスタムクライアントからの呼び出しであるかを格納します。この変数は、APIパスに一致するフィルターが実行された場合にのみ設定されます。私が直面している問題は、APIに対してリクエストが行われ、threadlocal変数がtrueに設定された場合、後続のリクエスト(APIリクエストではない)でthreadlocal変数がtrueに設定されたままになることです。静的初期化子が原因でfalseに設定されるのではないかと思われます。それでもtrueに設定できる唯一の方法は、初期化子が実行されない場合です。これにより、スレッドが再利用されていると思われます。これは本当ですか?

4

2 に答える 2

3

スレッドの再利用は、サーブレット実装の実装の詳細です。スレッドは通常、スレッドプールを介して再利用されます。これは通常、サーブレット構成を介して構成できます。残念ながら、これはGAEには当てはまりません。

ロギングを行うことで、GAEがスレッドをリサイクルするかどうかを簡単に確認できますThread.currentThread().getName()

スレッドの再利用の可能性があるため、ThreadLocalサーブレットでの使用は常に悪い考えでした。servletRequest.setAttribute(..)リクエストスコープにデータを保存する必要がある場合に使用します。

于 2012-08-30T08:49:02.577 に答える
0

static {...}は1回だけ呼び出されます(クラスローダーごとに、クラスが最初にメモリにロードされるとき)。

各スレッドのadlocal値を設定する必要があります。

public abstract class Foo {
    private static final ThreadLocal<Boolean> threadIsApiCall = new ThreadLocal<Boolean>();

    public static void yourFirstMethodInvokedByCustomClient() {
         threadIsApiCall.set(false);
    }

    public static void yourFirstMethodInvokedByRESTAPI() {
         threadIsApiCall.set(true);
    }

    public static void anotherLaterMethod() {
         boolean isAPI = threadIsAPICall.get();
         ...
    }
}
于 2012-08-30T02:54:17.780 に答える