#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’, поскольку они синхронизированы с одним и тем же объектом.