13

私は次のようなコードに数回出くわしました

class Foo {
   private Object lock = new Object();

   public void doSomething() {
      synchronized(lock) {
         ...

私が興味を持っているのは、なぜ書き込みではなくロックオブジェクトが作成されるのかということsynchronized(this)です。ロックの共有を有効にするためにありますか?最適化だと読んだのをぼんやりと覚えています。本当?また、ある文脈では、ロックを次のように宣言することは理にかなっていfinalますか?

4

4 に答える 4

24
  1. thisオブジェクト自体が外部からのロックとして使用されると、内部同期が中断されるため、同期をオンにすることはお勧めしません。また、synchronizedメソッドはthisロックとしても使用されているため、望ましくない影響が生じる可能性があることに注意してください。
  2. ロックを宣言することは、ロックオブジェクトがブロック内で再割り当てされ、異なるスレッドが異なるロックオブジェクトを参照finalする状況を防ぐために推奨されます。synchronizedこの他の質問を参照してください:可変オブジェクトのロック-なぜそれが悪い習慣と見なされるのですか?
于 2012-06-30T15:39:15.157 に答える
4

を持っthread1thread2アクセスmethod1し、thread3thread4アクセスするシナリオを想像してみてくださいmethod2。onと同期すると、thisブロックされ、アクセスしている場合、またはアクセスしている場合、これは発生しないはずであり、とは関係ありません。このための最適化は、クラスインスタンス全体をロックする代わりに、2つの異なるロックを使用することです。thread3thread4thread1thread2method1thread3thread4method1

これを反映したJavaDocで見つけた素晴らしい段落は次のとおりです。

同期されたステートメントは、きめ細かい同期で並行性を向上させるのにも役立ちます。たとえば、クラスMsLunchに2つのインスタンスフィールドc1とc2があり、これらが一緒に使用されることはないとします。これらのフィールドのすべての更新は同期する必要がありますが、c1の更新がc2の更新とインターリーブされるのを防ぐ理由はありません。そうすると、不要なブロッキングが作成されるため、同時実行性が低下します。

于 2012-06-30T16:01:13.157 に答える
0

java.util.concurrentパッケージのロックの使用を検討してください。
これにより、たとえば、より最適化されたロックが提供される場合があります。ReadWriteLockを使用すると、すべてのリーダーが待機せずにアクセスできるようになります。

于 2012-06-30T17:08:19.330 に答える
0

これが「ReentrantReadWriteLock」の完全な動作例です。

 public class DataReader  {
 private static final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
 private static final Lock read = readWriteLock.readLock();
 private static final Lock write = readWriteLock.writeLock();
 public static void loadData() {
  try {
   write.lock();
   loadDataFromTheDB());
  } finally {
   write.unlock();
  }
 }

 public static boolean readData() {
  try {
   read.lock();
   readData();
  } finally {
   read.unlock();
  }
 }

 public static List loadDataFromTheDB() {
     List list = new ArrayList();
  return list;
 }

    public static void readData() throws DataServicesException {
     //Write reading logic
    }
}
于 2012-07-01T01:55:08.033 に答える