Дайте классу C ++ foo, внутри он имеет синхронизированный метод. Как гарантировать, что синхронизированный метод доступен только одному потоку - PullRequest
2 голосов
/ 16 декабря 2011

Дайте класс C ++ foo, внутри он имеет синхронизированный метод. У нас есть два объекты foo, named, f1 и f2, если одновременно запущены f1 и f2, Можем ли мы гарантировать доступ к синхронизированному методу только одним потоком?

Моя идея:

Используйте мьютекс, кто хочет получить доступ к методу, кто получит мьютекс.

Этот вопрос интервью не так прост.

Какие-нибудь решения?

спасибо

Ответы [ 4 ]

8 голосов
/ 16 декабря 2011

В Java, если метод не является статическим, вам необходимо выполнить внешнюю синхронизацию, чтобы гарантировать, что метод вызывается только одним потоком за один раз.

Вы также можете синхронизировать сам метод со статической переменной класса. Э.Г.

public class myClass
{
  private static Object myLock = new Object();

  public void myMethod()
  {
    synchronized(myLock)
    {
      // ...
    }
  }
}
3 голосов
/ 16 декабря 2011

С помощью статического метода вы будете делать в Java следующее:

class Foo {

   public static synchronized void mymethod() {
      ...
   }
}

В этом случае вы фактически синхронизируете на Foo.class.

Если у вас есть метод экземпляра (т.е. не статический), и вам нужно синхронизировать, вы можете поместить в метод блок synchronized и синхронизировать любой объект, даже в самом классе:

public void mymethod() {
  synchronized( Foo.class ) {
    ...
  }
}

Обратите внимание, что это синхронизирует доступ к другим статическим синхронизированным методам в том же классе du с объектом общей блокировки Foo.class.

Кстати, ответ на этот вопрос зависит от определения доступ к : несколько потоков могут получить доступ к методу, пытаясь вызвать его, прочитать его метаданные отражения или даже ввести его в случай вложенных синхронизированных блоков, но обычно они не выполняют одновременно, если только части метода не синхронизированы (или не синхронизированы с другим объектом блокировки).

0 голосов
/ 17 декабря 2011

Если у вас есть два разных экземпляра класса foo, то не имеет значения, что происходит, потому что у каждого своя копия метода, и синхронизация происходит на объекте this:

public synchronized void method() {
    // code
}

эквивалентно:

public void method() {
   synchronized(this) {
      // code
   }
}

Сказав это, если каждый поток вызывает method из другого экземпляра foo:

  1. , они получат разные блокировки
  2. они не приведут к гонке данных, если вы не изменяете данные вне класса foo
0 голосов
/ 16 декабря 2011

Если я вас правильно понимаю, и вы хотите, чтобы он был синхронизирован во всех случаях, сделайте метод статически синхронизированным

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...