2

このスレッドローカルパターンに従ってvaadinアプリケーションを実装しています。

アプリケーションの状態は、いくつかのワーカースレッドによって変更されます。したがって、アプリケーションの状態が変化したことをアプリケーションに通知するために、進行状況インジケーターを追加します。

進行状況インジケーターのサンプルを読むと、次のように表示されます。

        // All modifications to Vaadin components should be synchronized
        // over application instance. For normal requests this is done
        // by the servlet. Here we are changing the application state
        // via a separate thread.
        synchronized (getApplication()) {
            prosessed();
        }

getApplicationしたがって、基本的には、アプリケーションのインスタンスを取得するために呼び出しを変更する必要があると思います(呼び出すだけですgetCurrent)。

  private static ThreadLocal<MyApplication> currentApplication = new ThreadLocal<MyApplication>();

    @Override
    public void init() {
        setCurrent(this); // So that we immediately have access to the current application

        // initialize mainWindow and other stuff

        // Register a transaction listener that updates our ThreadLocal with each request
        if (getContext() != null) {
            getContext().addTransactionListener(this);
        }   
    }

    /**
     * @return the current application instance
     */
    public static MyApplication getCurrent() {
        return currentApplication.get();
    }

問題は、アプリケーションでミューテックスを取得できないため、ワーカースレッドが飢餓状態で停止することです。vaadinフォーラムが提供する1つの解決策は、InheritableThreadLocalを使用することです。動作しますが、理由がわかりません。

javadocから:

このクラスはThreadLocalを拡張して、親スレッドから子スレッドへの値の継承を提供します。子スレッドが作成されると、子は、親が値を持つすべての継承可能なスレッドローカル変数の初期値を受け取ります。通常、子の値は親の値と同じになります。ただし、このクラスのchildValueメソッドをオーバーライドすることにより、子の値を親の任意の関数にすることができます。

継承可能なスレッドローカル変数は、変数で維持されているスレッドごとの属性(たとえば、ユーザーID、トランザクションID)を、作成された子スレッドに自動的に送信する必要がある場合に、通常のスレッドローカル変数よりも優先して使用されます。

ワーカースレッドは初期値を受け取らないため、ロックを取得できませんか?私は何かを誤解していますか?この問題を除いて、私が知っておくべきInheritableThreadLocalを使用することの潜在的な落とし穴は何ですか?

ありがとう。

4

1 に答える 1

3

それがどのように機能するかを理解するための重要なポイントは、ThreadLocalクラスのメソッドです。

static ThreadLocalMap createInheritedMap(ThreadLocalMap parentMap) {
   return new ThreadLocalMap(parentMap);
}

スレッドコンストラクタからのみ呼び出されるように設計されています。方法

protected Object childValue(Object parentValue)

of classは、子スレッドInheritableThreadLocalの変数の初期値を、親スレッドの変数(パラメーターとして渡される)の関数として設定するために使用されます。このメソッドは、子スレッドが作成される前に親スレッド内から呼び出され、デフォルトの実装では子の値が親の値と同じになりますが、メソッドをオーバーライドして、子の値を親の値の関数として設定できます。親スレッドの値。デフォルトでは、は同じ入力引数を返しますが、メソッドをオーバーライドすると、この動作も変更される可能性があります。InheritableThreadLocalThreadLocalchildValue()ThreadLocalschildValue()childValue()

したがって、InheritableThreadLocalほぼ同じようThreadLocalに機能し、同じ同期の落とし穴があります。

于 2012-11-06T12:00:58.323 に答える