Java синхронизированный вопрос - PullRequest
6 голосов
/ 11 сентября 2010

Я новичок в Java Threads и синхронизации.

Допустим, у меня есть:

public class MyClass(){

    public synchronized void method1(){ 
        //call method2();
    } 

    public synchronized void method2(){};

}
  1. Что это значит, когда я синхронизирую method1()на объекте экземпляра?Итак, когда поток получил блокировку при попытке доступа к synchronized method1(), мешает ли он другим потокам получить доступ к другому synchronized method2() из того же объекта?

  2. Допустим, поток получаетблокировка при доступе к method1 (), но допустим, что method1() вызывает method2(), что также synchronized.Это возможно?Я имею в виду, есть ли какие-либо правила, которые могут помешать method1() звонить method2()?

Заранее спасибо.

Ответы [ 4 ]

7 голосов
/ 11 сентября 2010
  1. Да, использование модификатора метода synchronized в нестатическом методе означает, что он использует монитор экземпляра, для которого вызывается метод, и это используется всеми такими методами.
  2. Нет - поток уже принадлежит монитору, поэтому он может свободно вводить другие блоки, защищенные этим же монитором.
4 голосов
/ 11 сентября 2010
  1. См. Здесь :

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

  2. Поскольку этот поток удерживает блокировку текущего объекта, он может вызвать method2(), а другой поток не может.

2 голосов
/ 11 сентября 2010

(1) Это эквивалентно:

public void method1(){ 
    synchronized (this) {
        ...
    }
}

Так что он синхронизируется на текущем экземпляре. Если мы переписываем method2 таким же образом ...

public void method2(){ 
    synchronized (this) {
        ...
    }
}

... тогда вы можете ясно видеть, что они блокируются на одном и том же объекте, и поэтому другие потоки не могут вызывать method1 или method2, пока method1 не выйдет из своего блока synchronized.

(2) synchronized блоки являются входящими, это означает, что один и тот же поток может вводить другие блоки synchronized, которые блокируют один и тот же объект столько раз, сколько он хочет. Насколько я понимаю, каждый раз, когда вы входите в блок synchronized, Java увеличивает счетчик объекта, с которым вы синхронизируете, на 1, и каждый раз, когда вы выходите из блока synchronized, он уменьшает его. Когда этот счетчик достигает 0, блокировка снимается.

2 голосов
/ 11 сентября 2010

Примечание к вопросу 2, method1 () также может вызывать синхронизированные методы также в других классах , что может привести к взаимоблокировке:

Thread1 вызывает синхронизированный метод method1 (), который, в свою очередь, должен вызвать синхронизированный метод method_b () в AnotherClass Thread2 удерживает блокировку на AnotherClass и выполняет метод, который должен вызвать method1 () в классе, блокировка которого удерживается Thread1

Оба потока заблокируют ожидание освобождения блокировки другим, тупик.

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