Потоки Java и синхронизированные блоки - PullRequest
8 голосов
/ 14 марта 2011

Предположим, я выполняю блок кода synchronized внутри некоторого потока, а внутри блока synchronized я вызываю метод, который порождает другой поток для обработки синхронизированного блока кода, который требует такой же блокировки, что и первый метод.Так что в псевдо-Java-коде:

public void someMethod() {
  synchronized(lock_obj) {
    // a whole bunch of stuff...

    // this is the last statement in the block
    (new Thread(someOtherMethod())).start();
  }
    // some more code that doesn't require a lock
}

public void someOtherMethod() {
  // some setup code that doesn't require a lock

  // return the stuff we want to run in another thread
  // that does require a lock
  return new Runnable() {
    @Override
    public void run() {
      synchronized(lock_obj) {
        // some more code
      }
    }
  };
}

Я понятия не имею, как понять этот код.То, что я написал, даже законно?Синтаксически я не вижу никаких проблем, но я не уверен, как рассуждать с помощью такого кода.Поэтому, когда я выполняю someOtherMethod(), чтобы создать экземпляр Runnable, в какой области видится код перед выполнением оператора return?Это выполняется как часть первого синхронизированного блока?Предположим, что есть и другие работающие потоки, которые могут потребовать блокировки на lock_obj.

Ответы [ 3 ]

9 голосов
/ 14 марта 2011

Вы по-прежнему удерживаете блокировку во время создания runnable и потока, но после вызова start и до того, как поток на самом деле подхватывает, вы снимаете блокировку.Новый поток должен будет конкурировать за блокировку с другими потоками.

6 голосов
/ 14 марта 2011

В этом коде нет ничего плохого. Перед оператором возврата в someOtherMethod() код выполняется в синхронизированном блоке someMethod(). После запуска нового потока он будет блокировать оператор synchronized внутри метода run() до тех пор, пока не получит блокировку на lock_obj (самое раннее, когда someMethod() выходит из своего синхронизированного блока).

0 голосов
/ 14 марта 2011

Если вначале вызывается someMethod (), это классический пример тупика.

Правильно ли то, что я написал?
---- Да, это прекрасноюридически синтаксически.

Итак, когда я выполняю someOtherMethod () для создания экземпляра Runnable, в какой области видимости выполняется код перед оператором return? ---- ЕслиsomeOtherMethod () вызывается изнутри someMethod (), а затем в область синхронизированного блока метода someMethod ().

...