синхронизированный метод внутреннего класса

#java #inner-classes

#java #внутренние классы

Вопрос:

Если метод внутреннего класса помечен как синхронизированный, какая блокировка фактически приобретается для этого метода? Внешний объект или внутренний объект?

Изначально я думал, что это внутренний объект, но когда я увидел фрагмент кода: sample inner class, stateMachine даже не является членом внутреннего класса, а является членом внешнего класса, поэтому я задаюсь вопросом, может быть, полученная блокировка является внешним объектом?

Спасибо

Ответ №1:

Он будет синхронизирован с объектом, членом которого является метод.

 public class SyncTest{
    class B{
        synchronized void runTest(){
            System.out.println("running");
        }
    }
    synchronized void check() throws Exception{
        B b = new B();
        new Thread( ()-> b.runTest() ).start();
        System.out.println("waiting");
        Thread.sleep(100);
        System.out.println("finished");
    }
    public static void main(String[] args) throws Exception {

        new SyncTest().check();
    }

}
  

В этом примере, если runTest был синхронизирован на внешнем объекте, поток не мог запуститься до тех пор, пока check метод не завершится. Однако на самом деле он синхронизирован с экземпляром внутреннего класса.

Это условие гонки, чтобы увидеть, когда выводится надпись «running». Это может быть сначала или после «ожидания», и редко когда, но, возможно, после «готово».

Мы можем изменить нашу программу ‘runTest’ для синхронизации с внешним экземпляром.

 synchronized( SyncTest.this ){
    System.out.println("running");
}
  

Теперь «running» всегда будет печататься последним, потому что ему приходится ждать завершения метода ‘check’, поскольку они синхронизированы с одним и тем же объектом.