может ли нить удерживать два замка одновременно?

Пример показывает, как возникает тупик. Есть одна вещь, которую я не понимаю, а именно то, что когда первый thead, который вызывает метод bow экземпляра alphone, собирается выполнить gaston.bowbBack (this), будет ли поток снимать блокировку и приобретать блокировку экземпляра gaston, если , предположим, он не принадлежит второму потоку? или он будет удерживать две блокировки одновременно, пока весь код метода не будет выполнен полностью? И еще вопрос, есть ли способ проверить, удерживает ли поток блокировку?

  public class Deadlock {
        static class Friend {
            private final String name;
            public Friend(String name) {
                this.name = name;
            }
            public String getName() {
                return this.name;
            }
            public synchronized void bow(Friend bower) {
                System.out.format("%s: %s"
                    + "  has bowed to me!%n",
                    this.name, bower.getName());
                bower.bowBack(this);
            }
            public synchronized void bowBack(Friend bower) {
                System.out.format("%s: %s"
                    + " has bowed back to me!%n",
                    this.name, bower.getName());
            }
        }

        public static void main(String[] args) {
            final Friend alphonse =
                new Friend("Alphonse");
            final Friend gaston =
                new Friend("Gaston");
            new Thread(new Runnable() {
                public void run() { alphonse.bow(gaston); }
            }).start();
            new Thread(new Runnable() {
                public void run() { gaston.bow(alphonse); }
            }).start();
        }
    }

person PMH    schedule 04.12.2014    source источник
comment
хорошо, в любое время, когда я вижу этот пример, я начинаю искать, чтобы закрыть его как дубликат, мы много над этим разбирались. и да, нет причин, по которым поток не может удерживать более одной блокировки одновременно. выбранный ответ в связанной публикации должен разъяснять, что происходит.   -  person Nathan Hughes    schedule 04.12.2014


Ответы (2)


1) поток может иметь более одной блокировки, например

    ...
    synchronized (obj1) {
        System.out.println(1);
        synchronized (obj2) {
            System.out.println(2);
        }
    }
    ...

2) мы можем проверить, удерживает ли поток блокировку с помощью Thread.holdsLock(Object obj)

person Evgeniy Dorofeev    schedule 04.12.2014

Поток не снимет блокировку, получив другую; он может удерживать несколько замков. Re: ваш второй вопрос, да, есть способ узнать, удерживает ли текущий поток блокировку монитора объекта (Thread # holdLock)

person Enno Shioji    schedule 04.12.2014