2つのスレッドが同じ静的メソッドを同時に呼び出すとどうなりますか?例えば:
public static String someMethod(){
//some logic, can take about 1 second to process
return new String(result);
}
最初のスレッドはsomeMethod()を呼び出します。 2番目のスレッドは0.5秒後にsomeMethod()を呼び出します(最初のスレッドはまだデータを処理しています)。
SomeMethod()を同期できることは知っています。しかし、同期されていない場合はどうなりますか?
メソッドが状態外で変化するかどうかによって異なります。
static long i = 0l;
public static String someMethod(){
String accm = "";
for(;i < Integer.MAX_VALUE*20/*Just to make sure Word tearing occurs*/; i++)
accm += i
return accm;
}
問題が発生します:
++
はアトミック操作ではありません。 {int n = i; i = i + 1; return n}
とまったく同じです。i = i + 1
もアトミックではありません。途中で変更すると、一部の値が繰り返されますただし、i
がローカル変数の場合、問題はありません。読み取り中に外部状態が不変であることが保証されている限り、問題が発生することはありません。
メソッドが呼び出されると、JVMは実行中のスレッドでの呼び出しに対してスタックフレームを作成します。このフレームには、メソッドで宣言されたすべてのローカル変数が含まれています。フィールドにアクセスしない静的またはその他のメソッドの場合、各実行は各スレッドで完全に独立して進行します。メソッドが計算にパラメーターを使用する場合、これらのパラメーターもスタックフレームに配置され、複数の呼び出しが互いに干渉することはありません。
メソッドが静的であるという事実は関係ありません。彼らの質問は、問題のコードによって操作されている状態変数である必要があります。
2つのステートメントが別々のスレッドで実行される場合、happens-beforeを確立しない限り、最初のスレッドの変更が2番目のスレッドに表示される保証はありません。特定の同期戦略を使用してsomeMethod()
を同期することによる、これら2つのステートメント間の関係。つまり、同じ変数に書き込んでから2つのスレッドから同時に読み取る場合、ロジックは予期しない予測できない結果をもたらす可能性があります。