このページの著者は、以下の 2 番目のコード例には同期の問題があるが、コードは 100 回で約 99 回動作すると述べています。そのページの 2 つのプログラムの動作上の違いはわかりません。
前の 2 つを組み合わせるやや一般的な解決策は、フィールドの値をローカル変数にコピーしてから、ローカル変数のみを変更することです。フィールドはメソッド内で変更されません。例えば、
public class Counter {
int count = 0;
public void count() {
int count = this.count;
int limit = count + 100;
while (count++ != limit) System.out.println(count);
}
}
ローカル変数 count がフィールド カウントをどのようにシャドウするか、および this キーワードを使用してシャドウの外側のフィールド カウントを参照する方法に注意してください。
このトリックは、メソッドが完了したときに、変更された変数をフィールドに戻す必要がない場合に主に役立ちます。以下は状態を保存しますが、まだ明らかでない同期の問題の影響を受けます。
public class Counter {
private int count = 0;
public void count() {
int count = this.count;
int limit = count + 100;
while (count++ != limit) System.out.println(count);
this.count = count;
}
}
実際、これは 100 回のうち 99 回は機能するため、元の例よりもさらに悪い可能性があります。ソース コードで見つけないと、このバグを特定するのは非常に困難です。