12

次の行に沿って、ロギングクラスで静的オブジェクトが定義されています。

   class myLoggingClass {
     static java.util.Properties properties;
     ...
     ...
   }

私の参考書によると、これはプロパティオブジェクトが私のクラスのすべてのインスタンスによって共有されることを意味します。

この定義では不十分だと思います。プロジェクトの各アプリケーションで複数回呼び出されるクラスを作成しています。

さらに、私たちのプロジェクトでは、同じTomcatコンテナで実行されている複数のWebサービスを使用しています。各Webサービスには複数のスレッドが含まれる場合があります。

ホスト上で実行されているJava仮想マシンは、Tomcatの外部で実行される1つ以上のWebサービスクライアントアプリケーションを実行する場合もあります。

したがって、この定義により、Tomcatがスレッドを使用して複数のWebサービスを実行し、それぞれに複数のオブジェクトがあり、クラスのインスタンスが含まれている場合があります。

また、Tomcatの外部で、同じJVM内で実行されている1つまたは2つのWebクライアントが存在する場合もあります。私のクラスのこれらのインスタンスはすべて同じプロパティオブジェクトを共有しますか?これにより、JVM全体になります。

静的オブジェクトがJVM全体ではない場合、それぞれがどのレベルに存在するかを誰かが知っていますか?Tomcatコンテナごとに1つ?Webサービスごとに1つ、スタンドアロンWebサービスクライアントアプリケーションごとに1つ?

理由:プロパティを更新すると、java.util.Propertiesからjava.lang.ConcurrentUpdateExceptionが発生します。

クラスが更新するときにプロパティオブジェクトを「ロック」するために静的ブール変数を使用していますが、これは例外の発生を妨げていません。

これにより、私のクラスで使用されている静的オブジェクトは、java.util.Propertiesで使用されているものと同じスコープレベルではない可能性があると私は信じています...しかし、それは単なる推測です。

助けてくれてありがとう。

4

4 に答える 4

19

静的は「クラスのすべてのインスタンスによって共有される」わけではありません。インスタンスとは無関係です。それらはタイプ自体に属します。特に、静的変数は、インスタンスを作成しなくても完全に使用できます。

これは、スタティックのスコープに関する手がかりを与えます: それらは、それをロードしClassた によってスコープされる、包含クラスを表すオブジェクトによってスコープさClassLoaderれます。

ライブラリが配置されている場所に応じて、静的変数はJVM全体またはWebアプリケーション全体である可能性があります.Tomcatが複数のホスティングをサポートしている場合(私は覚えていません).

ライブラリがどのように配置されているか、およびライブラリがクラスローダーとどのように関連しているかについては、Tomcat のドキュメントを参照してください。たとえば、Tomcat 6.0 ClassLoader ハウツー ガイドは次のとおり、5.5 に相当します。

ブール値の「ロック」はどのように機能しますか? 適切なロック ( ) を実際に使用してsynchronized、プロパティ オブジェクトのすべての使用 (読み取りと書き込みの両方、反復処理中の全期間のロックを含む) が適切にロックされていることを確認する必要があります。

「ライブ」Propertiesオブジェクトを変更する代わりに、それを不変として扱うことを検討しましたか?プロパティを更新する場合は、コピーを取得して変更し、そのコピーを「ライブ」バージョンにしますか? 2 つの異なるスレッドが同時に変更を行うのを防ぐ必要がありますが (そうしないと一部が失われます)、読み取り側がはるかに簡単かつ効率的になる可能性があります。

于 2009-09-09T20:59:12.410 に答える
5

このようなstatic変数のスコープは、クラスをロードした ClassLoader ごとに 1 つに制限されていることがあります。Tomcat がその ClassLoader をどのように配置するかはわかりません。そのため、その環境でスコープの範囲がどの程度になるかを言うのは困難です。

于 2009-09-09T20:58:01.540 に答える
3

考えられる原因は、あるスレッドでオブジェクトConcurrentModificationExceptionの値/エントリを反復処理しているときPropertiesに、別のスレッドが同時にオブジェクトを変更していることです。これはできません。

ここで言及しているロックメカニズムについて詳しく教えてください。

クラスが更新するときにプロパティオブジェクトを「ロック」するために静的ブール変数を使用していますが、これでは例外が発生しません。

?

Java に組み込まれているロックおよび同期メソッドを使用しているようには聞こえないからです。

このようなものは、別のスレッドが更新している間、スレッドが Properties オブジェクトを読み取らないようにする必要があります。

static Object lockObject = new Object();

...

synchronized(lockObject) {
     // access the Properties object
}

これは、Properties オブジェクトにアクセスするたびに、読み取りまたは変更するために行う必要があることに注意してください。

また、静的オブジェクトがすべてのインスタンスまたは静的 lockObjects 間でデータを共有することは決してお勧めしません - グローバル データは悪です - しかし、何らかの理由でこれが必要であるかのように聞こえます。

于 2009-09-09T21:07:23.473 に答える
0

クラスを含む jar が異なるアプリケーションの各 WEB-INF/lib で複製されるクラスローダーの問題でしょうか? もしそうなら、私はこの jar をアプリケーションではなく Tomcat ライブラリに追加しようとします。

于 2009-09-09T21:06:54.437 に答える