この状況でTerracottaはどのように機能しますか?
-
03-07-2019 - |
質問
つまり、 N サイズのサーバーアレイを次のようにセットアップしたとします。
代替テキストhttp://www.terracotta.org/web /download/attachments/43909161/ServerArrayMirrorGroup.png
単純なJavaBean / POJOがあります:
package example;
public class Person {
private OtherObject obj;
public void setObj(OtherObject theObj) {
synchronized (this) {
obj = theObj;
}
}
public OtherObject getObj() {
synchronized (this) {
return obj;
}
}
}
クライアントの1つがTCルート(データ構造)のPersonオブジェクトでPerson.setObj(OtherObject)を呼び出す場合、同期ブロックは(Person.setObj(OtherObject)で)そのクライアントが保持していた:
1) N サイズのサーバーアレイ内のすべての N サーバーがそのPerson.obj属性と同期/更新されるまで?
または
2)「アクティブ」になるまでサーバーは、更新されたPerson.obj属性と同期されていますか?次に、アレイ内の他の( N-1 )サーバーは可能な限り同期されますか?
または
3)私が見ている他の方法?
解決
答えは実際には1または2ではありません。オブジェクトはサーバーミラーグループ全体にストライプされます。このフィールドを初めて設定すると、トランザクションが作成され、その最初のトランザクション用に選択されたそのミラーグループが「所有」します。その後のオブジェクト。
1と2の両方に関して、すべてのアクティブなサーバーグループを更新する必要はないため、これらの条件のいずれかを待つ必要はありません。
Terracottaサーバーアレイの構成に関する詳細は、Terracottaのドキュメントを参照してください。
ロックの観点から、オブジェクトの変更を実行している間、このPersonオブジェクトのクラスター化されたロックは保持されます(クラスター全体で相互排除)。同期ブロックの範囲は、上記のトランザクションを形成します。 getObj()メソッドでは、これを読み取りロックとして設定して、クラスター全体で複数の同時読み取りを許可できます。
他のヒント
他のすべてのユーザーがオブジェクトへの参照を持ち、実行中/実行中/実行後にオブジェクトに触れることができると仮定します。したがって、解決策はロックを追加することであり、
- ロックを取得
- オブジェクトの変更
- ロックを解除
それはまさに synchronized が行うことです...キューを作成し、 synchronizedメソッドを複数回呼び出すことはできません...しかし、基礎となるオブジェクトはどこかで参照されている場合は触れてください。
参照:
私は彼らの(Terracotta)の実装に精通していませんが、JMMの観点からは、クラスター全体のロックを取得する必要があります 。ただし、この例は非常に単純です。単なる参照の変更であり、それにより、揮発性の書き込みのようなものに変換され、ロックを完全に回避する可能性があります。
しかし、あなたが同期ブロックで自明ではないことをすると、同期ブロックの開始時にTCが悲観的にcluser全体のロックを取得すると仮定します。そうしないと、JMM仕様と矛盾することになります。私が理解しているように。
つまり、オプション#1。したがって、クラスターで共有するものに注意し、可能な場合は不変オブジェクトとjava.util.concurrent。*データ構造を使用してください。後者はTCで特別な本質的な愛を獲得しています。