Синхронизированный метод - это то же самое, что и код всех этих методов в
synchronized(this) {
/// code here ...
}
блок.
Для данного экземпляра объекта o , только один поток может одновременно запускать любой блок synchronized (o) . Любой другой поток, который пытается это сделать, будет плакать до тех пор, пока поток, который запускает этот блок (имеет синхронизированную блокировку ), не выйдет из этого блока (освободит блокировку).
В вашем случае тупик возникает, когда Альфонс начинает кланяться в потоке 1, тем самым входя в синхронизированный блок. Поток 1 затем вытесняется системой, так что поток 2 может начаться и получить поклон Гастона. Но Гастон пока не может поклониться, потому что он синхронизируется на Alphonse, и у Thread 1 эта блокировка уже есть. Таким образом, он будет ожидать, когда поток 1 покинет этот блок. Затем система вернет нить 1 обратно, что попытается заставить Альфонса преклониться. За исключением того, что он не может сделать это, потому что поток 2 имеет синхронизированную блокировку на Gaston. Обе Нити теперь застряли, ожидая, пока другая закончит поклон, прежде чем сможет поклониться назад ...