をどこにでも置くよりも、あなたのクラスが必要とする不変量を注意深く推論してから、それらの不変量を保証するのに十分なだけ同期してください。
- デッドロック
- 生存性の問題
デッドロックの誰もが知っている:あなたの過同期する場合、次の2つのリスクを作成します。ライブラリーの問題は、同期のコストとは関係ありませんが、マルチスレッド・アプリケーションですべてをグローバルに同期させると、モニターを待つことを待っているスレッドがブロックされます。なぜなら、別のスレッドは、モニター。
安全のためにキーワードをどこにでも叩きたい場合は、の代わりにfinal
を使用することをおすすめします。 :)
final
を作ることで、スレッドの安全性が向上し、ロックによってどの不変条件を維持する必要があるのかを簡単に推論できます。一例を与えるために、あなたはこの些細なクラスを持っているとしましょう:上記のクラスで
public class SimpleClass {
private volatile int min, max;
private volatile Date startTime;
// Assume there are many other class members
public SimpleClass(final int min, final int max) {
this.min = min;
this.max = max;
}
public void setMin(final int min) {
// set min and verify that min <= max
}
public void setMax(final int max) {
// set max and verify that min <= max
}
public Date getStartTime() {
return startTime;
}
}
を、minまたはmaxを設定するとき、あなたは同期させる必要があります。上記のコードは壊れています。このクラスはどのような不変式を持っていますか?複数のスレッドがsetMin
またはsetMax
を呼び出す場合でも、常にmin <= max
を確保する必要があります。
1つのスレッドがsetMin
を呼び出し、別のスレッドがgetStartTime
を呼び出して、第二のスレッドが不必要にsetMin
戻るまでブロックされます、その後場合は、これは多くの変数の大きなクラスであり、あなたはすべてを同期すると仮定。多くのメンバーを持つクラスでこれを行い、守らなければならない不変条件に少数のメンバーしか関与していないと仮定すると、すべてを同期させることはこの種の多くの生存問題を引き起こします。
ブラックボックスの材料から飛行機を作っていないのと同じ理由は... –