同じアプリケーションの2つのインスタンスをTomcat(または他のサーバー)の単一のインスタンスにデプロイして実行した場合。次に、(Singletonクラスの)単一のオブジェクトが作成されます。
それで、本質的に私はいつもシングルトンクラスの単一のオブジェクトがJVMごとに作成されるケースであるということを理解したいですか? Webサーバー(またはコンテナー)でホストされているアプリケーションの場合、これはどのように機能しますか。
シングルトンクラスがあり、Tomcatでこのクラスを使用する2つのWebアプリケーションを実行する場合、両方のWebアプリケーションは、Tomcatを実行するJVMでこのシングルトンの2つの異なるインスタンスを取得します。
ただし、WebアプリケーションがJREまたはTomcat共有ライブラリのシングルトンを使用する場合、たとえば、Runtime.getRuntime Webアプリケーションは同じランタイムのインスタンスを取得します。
これは、TomcatがWebアプリケーションに個別のクラスローダーを使用するためです。 webappクラスローダーがクラスをロードするとき、最初にwebappクラスパスでクラスを見つけようとしますが、クラスが見つからない場合は、親クラスローダーにクラスのロードを要求します。
シングルトンは通常、ClassLoader
のみに関連付けられます。
したがって、.warファイル内の.classファイルに基づくシングルトンがあり、このWebアプリケーションを複数回デプロイする場合、各アプリケーションは独自のシングルトンを取得します。
一方、シングルトンの.classファイルがTomcat
のクラスパスにある場合、インスタンスは1つしかありません。この.classは特定のWebアプリケーションに属していません(Tomcat
インスタンスに属しています)。
両方の場所にシングルトンがある場合、それはクラスローダーの階層に依存し、「最初に親」または「最初にWebアプリケーション」を選択できます。
シングルトンに対して常に同じClassLoader
をクエリすることを保証することにより、そのようなシングルトンを作成することが可能です。私はこの他の答えで 広範な説明 を書きました。
JVMアナロジー:
JVMは大邸宅のようなものです。これには、サーバーアプライアンスとライブラリを組み合わせたファミリが含まれています。
ClassLoaderはファミリーメンバーであり、各ファミリーメンバーは1つのClassLoaderを表します(継承階層ではなくデリゲート階層として機能します)。注:ClassLoaderはクラスであり、複数のインスタンスを作成できます。
アプリケーションはアプライアンスのようなものです。例:洗濯機、冷蔵庫、空気冷却器、テレビ、ダイニングテーブル、ソファーなど...
ライブラリは、それぞれ独自のライブラリを持っています。親のライブラリが見つからない場合は、すべて自分のライブラリを検索します。
制限:父親がアプライアンスを購入した場合、子供はそれを使用できますが、親や兄弟は使用できません。各アプリケーションは、同じライブラリの異なるバージョンを使用する場合があります。つまり、ライブラリに同じ本の2つ以上のバージョンが含まれている場合は、最初に入手可能な本を選択します。
各ファミリ番号は、一意のアプライアンスを1つだけ使用できます。
家庭では、同じバージョンの複数のアプライアンスを使用できます。したがって、JVMを使用すると、同じバージョンの複数のアプリケーションを実行できます。
ガベージコレクターはマンションのサーバントで、デーモンとしてローミングし、あらゆる種類のオブジェクトをクリアできます。
静的変数のスコープは、ClassLoaderごとに1つに制限されています。
<shakey-ground>
私の知る限りでは、シングルトンはクラスローダーごとに一意です。したがって、あなたの質問に対する答えは、コンテナがWebアプリケーションをロードする方法に依存すると思います。
Webアプリごとに1つのクラスローダーを割り当てる場合、2つの完全に独立したシングルトンオブジェクトを取得するように見えます。 1つのクラスローダーを割り当て、すべてのWebアプリがそれを使用する場合、同じ一重項の1つのインスタンスを共有します。</shakey-ground>