1) RMI リモート メソッドを同期として実装した場合、それらは相互に排他的であることが保証されますか? RMI メソッド (クライアントに提供されるメソッド) が 2 つ同時に実行されないようにする必要があります。
RMI は (EJB とは異なり) それ自体ではそのような保証を提供せず、何らかの同期を実装しない限り、同じリモート オブジェクトに対する 2 つの呼び出しが同時に実行される可能性があります。あなたのアプローチは正しいです。すべてのメソッドを同期すると、同じオブジェクトで同時に 2 つのメソッドが実行されないようになります。注: キーワードsynchronized
のみは と同等synchronized( this )
です。
2) サーバーが定期的に実行するメソッドがあります。クリーンアップを行うために使用されます。リモートクライアントによって実行/使用されているRMIメソッドがある場合、この特定のメソッドが実行されないようにする必要があります。
クリーンアップ ジョブが別のクラスにある場合は、リモート オブジェクトとクリーンアップ ジョブの間で共有するロックを定義する必要があります。リモート オブジェクトで、ロックとして使用するインスタンス変数を定義します。
protected Object lock = new Object();
慣例により、人々はObject
この目的で を使用します。synchronized( remoteObj.lock ) { ... }
次に、同じパッケージにあると仮定して、定期的なジョブでロックを取得する必要があります。
リモート オブジェクトの他のメソッドは、同じ方法で同期する必要があります (synchronized
単独では十分ではありません)。これにより、リモート メソッド呼び出しと定期的なジョブの両方が排他的になります。
RMI メソッドを静的に実装し、そのクリーンアップ メソッドを RMI インターフェイス内に含めることを検討しましたが、問題を解決するエレガントな方法ではないようです。
また、RMI インターフェイス内のクリーンアップ メソッドを同期として記述しました。テストのために実行したところ、メソッド間に衝突はないように見えましたが、確信が持てません。
よく分かりましたら、クリーンアップロジックを静的メソッドにしたいですか?単独の静的メソッドはsynchronized
、クラスのロックを取得します。synchronized
オブジェクト インスタンスのロックを取得する「通常の」メソッド。これらは同じ暗黙のロックではありません!
しかし、インスタンス化されたリモート オブジェクトが1 つしかない場合は、ロックを静的にすることができます (これはクラスのロックと同じですが、少しクリーンです)。クリーンアップ コードも静的にすることができ、リモート オブジェクトと同じクラスにすることも、同じクラスにすることもできます。
スケルトン:
public class MyRemoteClass {
public static Object lock = new Object();
public void doStuff()
{
synchronized( lock ) { ... }
}
}
public class Cleanup {
public static void doIt()
{
synchronized( MyRemoteClass.lock ) { ... }
}
}