3

私はこのようなコードブロックを持っています:

if(supportsSomeStuff()){
     .....
     .....
}
else {
     .....
     .....
}

ここで、このコードブロックを複数の読み取り、単一の書き込みロックに入れたいと思います。この場合、ifステートメントをロックし、ifの後にロックを解除してから、elseステートメントをロックして、完了したら解放する方がよいでしょうか。

または、このif-elseケースのロックを1つだけ持って、完了したら解放できますか?

これを決定する必要がある場合、どのようなすべての要素を考慮する必要がありますか?

さらに詳しい情報が必要な場合はお知らせください。

4

5 に答える 5

1

次の2つのバリエーションを検討していますか?

synchronized(lock) {
    if(supportsSomeStuff()){
         .....
    }
    else{
         .....
    }
}

対。

if(supportsSomeStuff()){
    synchronized(lock) {
     .....
    }
}
else{
    synchronized(lock) {
     .....
    }
}

それらの間の唯一の(大きな)違いはif、後者の場合、ステートメント内の条件が同期されないことです。その上(supportsSomeStuff()複数のスレッドで実行できる場合)、前者の場合は少し長い時間ロックを保持しますが、それらは同等です。

于 2012-05-16T17:28:35.980 に答える
0

この方法で状態を変更している場合は、それをロックします

StringBuilderを変更し、changeingvalueという名前のStringBuilderをロックし、supportsSomeStuffがステートレスであるとします。

if(supportsSomeStuff()){
     //Considering that if will be executed when write needs to be done and else when read to be done 
     copyOnWriteStringBuilder = new StringBuilder(changingvalue.toString());//This will ensure that before every write you have taken a backup so concurrent read will see the last updated values
     synchronized(changingvalue) {
        //doSomething and then place the updated value in copyOnWriteStringBuilder too
     }
  }
else{
    return copyOnWriteStringBuilder; // This piece for read no locking
}
于 2012-05-16T17:28:38.430 に答える
0

私は言うだろう:

  • もちろん、ifまたはelseセクションのいずれかを介して一度だけロックおよびロック解除します。
  • モデルを使用lock(); try { ... } finally { unlock(); }して、意思決定に役立ててください。コードがよりクリーンな場合は、そのモデルの場合は全体をラップするだけで、それを使用します。

何かが足りない場合を除いて、次のようなものが最もクリーンだと思います。

lock.lock();
try {
   if(supportsSomeStuff()){
      ...
   } else {
      ...
   }
} finally {
   lock.unlock();
}

ifテストがロックされている必要がないことが心配な場合は、ロックしないでください。それについて心配する必要があるのは、テスト自体が、パフォーマンスに影響を与える可能性があり、ロックされたくない他のメソッドを呼び出す場合だけです。

于 2012-05-16T17:29:16.880 に答える
0

あなたは実際には、一般的な答え以上のものを与えるのに十分な情報を与えていません。

ただし、一般的には、次の間の最適な妥協点を見つけるようにしてください。

  • できるだけ短い時間ロックを保持します。
  • ただし、アトミックである必要がある操作のコード全体をロックしてください。

これらの競合する要素間の正確な妥協点は、状況によって異なります。

ちなみに、多くの人が組み込みの「同期」ロックを提案していますが、必要な書き込みスレッドは1つだけなので、状況によっては、ReentrantReadWriteLockを使用するとスループットが向上する場合があります。

于 2012-05-16T17:31:30.330 に答える
-1

読み取りは排他的ではありませんが、書き込みは排他的です。つまり、複数の同時読み取りが可能ですが、書き込みは1つのみであり、書き込みが発生した場合、読み取りは許可されません。

それはあなたがどこで何をするかに依存します。書き込むブロックを最小限に制限します。

于 2012-05-16T17:28:03.093 に答える