Вопрос о синхронизированных методах Java - PullRequest
3 голосов
/ 23 июня 2011

У меня есть класс с двумя синхронизированными методами:

class Service {

 public synchronized void calc1();

 public synchronized void calc2();

}

Оба требуют значительного времени для выполнения.Вопрос заключается в том, будет ли выполнение этих методов блокировать друг друга.Т.е. оба метода могут выполняться параллельно в разных потоках?

Ответы [ 3 ]

10 голосов
/ 23 июня 2011

Нет они не могут выполняться параллельно на одном и том же сервисе - оба метода используют один и тот же монитор (т. Е. this), и поэтому, если поток A выполняет calc1, поток B выигралне сможет получить монитор и не сможет запустить calc2.(Обратите внимание, что поток B мог бы вызвать любой метод для другого экземпляра из Service, хотя, поскольку он будет пытаться получить другой, не удерживаемый монитор, так как рассматриваемый this будет другим.)

Самое простое решение (если вы хотите, чтобы они работали независимо), было бы сделать что-то вроде следующего, используя явные мониторы:

class Service {
   private final Object calc1Lock = new Object();
   private final Object calc2Lock = new Object();

   public void calc1() {
       synchronized(calc1Lock) {
           // ... method body
       }
   }

   public void calc2() {
       synchronized(calc2Lock) {
           // ... method body
       }
   }

}

Рассматриваемые "блокировки" не должныиметь какие-либо особые способности, кроме того, чтобы быть объектами, и, следовательно, иметь определенный монитор.Если у вас есть более сложные требования, которые могут включать попытки немедленно заблокировать и откатиться назад, или запросить, кто держит блокировку, вы можете использовать фактические Lock объекты, но для базового случая этопростые Object замки в порядке.

1 голос
/ 23 июня 2011

Да , вы можете выполнять их в двух разных потоках, не путая внутренние компоненты вашего класса, но нет они не будут работать параллельно - только один из них будет выполняться в каждом время.

0 голосов
/ 23 июня 2011

Нет, они не могут быть. В этом случае вы можете использовать блок synchronized вместо синхронизации всего метода. Не забудьте синхронизировать разные объекты.

...