0

同期されたブロックについての説明を探しています。このクラスを検討してください-

public class A{
Map map;

 public getValue(String key){
  return map.get(key);
 }

 public remove(String key){
  synchronized(map){
   map.remove(key);
  }
 }
}

Aはシングルトンです。getValueは、複数のスレッドによってアプリ全体で頻繁にアクセスされます。マップからキーを削除する新しいメソッドremoveを追加しています。上記のようにremoveが実装されている場合、

  1. スレッドがremoveメソッドの同期ブロックにある場合、マップオブジェクトのロックを取得すると思います。これは、getValueメソッドを介してマップにアクセスしようとしている他のスレッドがブロックされることを意味しますか?(お願いします。)
  2. removeメソッドの同期ブロックにスレッドがない場合、getValueメソッドにアクセスするスレッドは通常どおり機能しますか?つまり、互いにブロックしませんか?(私もそれが欲しいです)。

削除操作を実行しているスレッドがある場合にのみ、getValueスレッドをブロックしたいと思います。

4

6 に答える 6

4

スレッドがremoveメソッドの同期ブロックにある場合、マップオブジェクトのロックを取得すると思います。これは、getValueメソッドを介してマップにアクセスしようとしている他のスレッドがブロックされることを意味しますか?

いいえ。これは、スレッドセーフなマップ実装を使用している場合を除いて、問題が発生していることを意味します。

removeメソッドの同期ブロックにスレッドがない場合、getValueメソッドにアクセスするスレッドは通常どおり機能しますか?つまり、互いにブロックしませんか?(私もそれが欲しいです)。

彼らはお互いをブロックしません、いいえ。繰り返しになりますが、使用している実装で問題がないことを確認する必要がありますが、書き込みと同時に読み取るよりも問題がない可能性Mapがはるかに高くなります。

ConcurrentMap実装(例)の使用を検討するConcurrentHashMap必要があります。その時点では、同期はまったく必要ありません。

それが使えない場合は、と-の両方で同期してパフォーマンスを 測定することをお勧めします。競合のないロックを取得するのはかなり安価です-本当にロックフリーにする必要がありますか?(もちろん、使用することは問題を回避するための非常に簡単な方法ですが、マイクロ最適化を開始する前に、必要なパフォーマンスを達成するために追加の複雑さが必要かどうかを常に考慮する必要があります。)getValueremoveConcurrentHashMap

于 2012-07-09T18:46:11.237 に答える
4

私があなたの必要性を正しく理解していれば、ConcurrentMapともちろん 、Java 5.0で導入され、あるレベルの並行性をサポートしていると私が信じているConcurrentHashMapを見ることができます。

于 2012-07-09T18:46:51.597 に答える
1

Mapインスタンスがどのようにインスタンス化されるかは示していませんが、スレッドセーフなコレクションインスタンスではないと仮定すると、このコードはスレッドセーフではありません

于 2012-07-09T18:46:36.623 に答える
0

synchronized(foo)同期の1つのルールは、同じfooに対して、一度に1つのスレッドのみがブロックに入ることができるということです。それがの唯一のルールですsynchronized

さて、メモリバリアなどについてはいくつかの複雑なことがあり、単一のスレッドがsynchronized(foo)同時に複数のネストされたブロックに存在する可能性がありますfoo

void thing() {
  synchronized(foo) {
    stuff(); // this works fine!
  }
}
void stuff() {
  synchronized(foo) {
    doMoreStuff();
  }
}

...しかし、上記のルールは基本的に理解するための鍵synchronizedです。

于 2012-07-12T09:36:11.337 に答える
0

1. getValue()は同期されていません。スレッドがオブジェクトのロックを取得すると、同期されていないブロックではなく、同期されたすべてのブロックを制御できます。 したがって、他のスレッドは次の場合にgetValue()にアクセスできます。スレッドはsychronized(map)ブロックにあります

2.同期されたMAPであるHashTableを使用します

于 2012-07-09T18:47:20.773 に答える
0

鶏が先か卵が先か

削除操作を実行しているスレッドがある場合にのみ、getValueスレッドをブロックしたいと思います。

ある種のスレッド間相互作用がなければ、を実行している他のスレッドがあるかどうかを判断することはできませんremove

実装する正しい方法getValue(...)は、マップ上で同期することです。

ConcurrentHashMap独自のロックを解除し、を使用して、並行パフォーマンスに多くの作業を利用することをお勧めします。

于 2012-07-09T18:47:31.787 に答える