編集:シングルトンのコンストラクターが複数回呼び出されていることがわかったので、クラスが別々のクラスローダーによって複数回ロードされているようです。Tomcatでグローバルシングルトンを作成するにはどうすればよいですか?私はグーグルしてきましたが、今のところ運がありません。
このように構築したシングルトンオブジェクトがあります。
private static volatile KeyMapper mapper = null;
public static KeyMapper getMapper()
{
if(mapper == null)
{
synchronized(Utils.class)
{
if(mapper == null)
{
mapper = new LocalMemoryMapper();
}
}
}
return mapper;
}
KeyMapperクラスは、基本的にHashMapの同期ラッパーであり、1つはマッピングを追加し、もう1つはマッピングを削除する2つの関数のみを備えています。32ビットWindowsマシンのTomcat6.24で実行すると、すべてが正常に機能します。ただし、64ビットLinuxマシン(OpenJDK1.6.0-b09を搭載したCentOS5.4)で実行している場合、マッピングを1つ追加し、KeyMapperが追加されたことを確認するために使用するHashMapのサイズを出力します(つまり、サイズ= 1を確認します)。次に、別のリクエストでマッピングを取得しようとしましたが、nullを取得し続け、HashMapのサイズを確認したところ0でした。削除するすべての呼び出しをコメントアウトしたので、マッピングが誤って削除されていないことを確信しています。 (そして、クリアや他のミューテーターは使用しません。取得して配置するだけです)。
リクエストはTomcat6.24(200スレッドと最低4スレッドを使用するように構成されています)を経由し、クラスが誤ってガベージコレクションを取得しないように-Xnoclassgcをjvmに渡しました(jvmも-serverモードで実行されています)。また、ガベージコレクションが行われていないことを確認するために、ガベージコレクションが発生した場合にstderrに出力するfinalizeメソッドをKeyMapperに追加しました。
私は気が遠くなり、HashMapのエントリが1分間あり、次のエントリがない理由がわかりません:(