1

2 つのメソッドがあり、各メソッドのステートメントが同期されているコードをテストしています。

private final Object obj1 = new Object();
private final Object obj2 = new Object();

public void method1(int result)
{
 //there's a loop to create delay

 synchronized (obj1){
   sum = sum + result;
 }

 //there's a loop to create delay

}


public void method2(int result)
{
  //there's a loop to create delay

 synchronized (obj2){
   sum = sum - result;
 }

 //there's a loop to create delay

}

私が基本的にやっていることは、合計に結果を追加し、同じ量を減算してから合計を出力することです。したがって、最初と最後の金額は一定でなければなりません。

問題は、2 つの diff オブジェクトをロックとして使用すると、最終的な量が最初の量と同じにならない理由がわからないことです。ただし、「this」オブジェクトを両方のステートメントのロックとして使用する場合は一定です。しかし、「this」をオブジェクトとして使用しても、同期されたメソッドを使用するよりも実行時間が速くなりませんでした。

私はまだ同期の概念に慣れていないので、助けていただければ幸いです。

4

2 に答える 2

2

ブロックでオブジェクトを指定するとsynchronize、そのオブジェクトはそのブロックのロックのように使用されますsynchronize。ロック オブジェクトを使用できるのは一度に 1 つのブロックのみです。

2 つの異なるオブジェクトをロックとして使用すると、それらは 2 つの異なるロックになります。2 つのスレッドが両方を同時にロックできます (ロックごとに 1 つのスレッド)。これにより、一貫性のない結果が説明されます。2 つのスレッドが 2 つの個別のロックを同時に取得し、それらをsum同時に変更する可能性があるため、計算が不正確になります。

単一のロックを使用して、単一のリソースを同時アクセスから保護する必要があります。を使用すると、次のようになりますthisobj1orobj2を両方のブロックで使用した場合も同じことが起こりますがsynchronize、この場合、オブジェクトのユーザーは、オブジェクトで同期し、意図的にロックを解除しないことで、メソッドを永久にブロックすることはできません。

于 2012-09-28T20:20:03.090 に答える
0

で操作を同期する場合は、両方のsynchronizedブロックが同じオブジェクト ( obj1(または)のいずれか) にある必要があります。obj2sum

それ以外の場合、各スレッドは 1 つのオブジェクトのロックを取得し、同時に操作を実行できます。

各スレッドは、保護されたコードを実行する前に、オブジェクトのロックを取得します。T1のロックを取得する可能性がObj1あり、同時にT2ロックを取得して実行を継続する可能性があるため、一貫性のない結果が生じる可能性があります。Obj2

于 2012-09-28T20:17:50.040 に答える