web-dev-qa-db-ja.com

静的変数はどのように分離されていますか?

私が持っている場合

_public class SomeClass {
    public static final HashMap hashmap = new HashMap();
}
_

次に、main(String[] args)メソッドを含む5つの異なるクラスを実行します。

_SomeClass.hashmap_にアクセスすると、同じHashMapにアクセスするのでしょうか、それとも、JVMで独自のhashmapを作成するのでしょうか?

8
ycomp

答えは「異なるクラスローダー内のクラスの各インスタンスは異なる」です。

2つの異なるJVMがある場合(Java MainOneおよびJava MainTwo)、これらは明らかに異なるクラスローダーです。ただし、ここでは、JVMを実行し続ける nailgun などのケースがまれにあり、複雑になります。

また、アプリケーションがIDE内から起動されたときなどの状況もあります。一部のIDEは、アプリケーションを実行するために新しいJVMを生成します。他のIDEは、独自のJVM内で新しいクラスローダーを起動する可能性があります(IDEがこれは非常にトリッキーになる可能性があります。

アプリケーションサーバー環境内で実行する場合、これは構成可能か、仕様を確認する必要があります。ただし、可能なすべての組み合わせが可能であることを認識してください。同じear内に2つのモジュールを分離できます(各.warには独自のクラスローダーがあります)、. ear全体でクラスローダーを共有できます。すべてが.jarクラスローダーを共有するファンキーな互換モードを使用できますが、それ自体が.warの分離されたクラスローダーにあるか、サーバー全体で1つのクラスローダーを使用することができます。一部のアプリケーションサーバーでは、異なるバージョンでの動作が変更されていることに注意してください(バージョン5より前のJBossは分離されていませんでしたが、バージョン5以降は分離されており、4.0.2は階層クラスローダーでしたが、4.0.3は統合クラスローダーに戻りました)。それは混乱です。したがって、「静的はクラスローダーごとに1つである」という認識が重要です。

Javaクラスローダーを使用したプログラム 内で実行可能なjarファイルを実行する)に示すように、単一のアプリケーション内に異なるクラスローダーを含めることも可能です。

したがって、「別のクラスローダー内のクラスの各インスタンスは異なる」という答えに戻ると、それは多くの異なる形式とEdge条件をとることができます。

11
user40980

一般に、JVMの利用可能なほとんどの実装では、新しいメインスレッドがそれぞれ新しいJVMで実行されるため、5つのクラスのそれぞれが独自のハッシュマップインスタンスを呼び出して使用します。 「Java」コマンドを使用してプログラムを実行すると、新しいJVMが作成されます。

これらの5つのメインクラスをテスタークラスから5つの異なるスレッドで呼び出すと、同じJVMでスレッドとして実行されます。その場合、同じハッシュマップを使用します。

https://stackoverflow.com/questions/18394560/when-multiple-Java-programs-run-on-the-same-machine

この質問を見ることができる興味深いシナリオがさらに2つあります。1つは、5つのメインクラスをサーバー上で個別のプログラムとして実行している場合、2つ目は、Java SDK。

アプリケーションサーバーの場合、通常は同じJVMと新しいクラスローダーが新しいプログラムごとに使用されるため、各メインクラスは独自のハッシュマップを取得します。マルチテナント環境では、同じハッシュマップが共有されます( http://www.ibm.com/developerworks/library/j-multitenant-Java/ )。

4
Apoorvaa Singh