Deadlock - dlaczego?

0

Witam
Jestem tu nowy, więc chylę czoła przed wszystkimi.

Mam pewien problem: znalazłem na stronie Oracle przykład kodu generującego deadlock. Wszystko fajnie, bo problem jest zrozumiały, przykład też wydawał się prosty.

http://docs.oracle.com/javase[...]ial/concurrency/deadlock.html

Oto kod:

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();
    }
}

Wszystko fajnie, bo uruchomiłem kod, faktycznie natychmiast występuje deadlock. Ale zaciekawilo mnie uzycie funkcji "format", kombinowałem przy tym kodzie, naszło mnie, żeby zmienić na "System.out.println" i - jakie zdziwko - nagle deadlock przestał się reprodukować.

Czy ktoś wie może dlaczego tak się dzieje? Dlaczego jak w powyższym kodzie zamieni się "System.out.format" na "System.out.println" (oczywiście zmieniając znaki procent na plusiki, żeby się kompilowało) to nie dostanie się deadlocka?

Pozdro

Mietek

1

Ok, już wiem. Chodzi o czas wykonania wątku. Można wywalić println i dać samego sleepa i deadlock sie zreprodukuje.

0

Deadlock nie ma nic wspólnego z funkcją format.

Problemem jest to, że mamy dwa wątki. Każdy z nich musi uzyskać dostęp jednocześnie do dwóch monitorów. Możliwe jest, że wątek 1 uzyska dostęp do monitora 1, a wątek 2 równocześnie uzyska dostęp do monitora 2. Obydwa wątki będą próbować uzyskać dostęp do brakującego monitora, ale to im się nie uda.

Rozwiązaniem jest np. to, aby obydwa wątki próbowały uzyskać monitory w tej samej kolejności (czyli, aby obydwa wykonywały "alphonse.bow(gaston);"). Ewentualnie można mieć tylko jeden wspólny monitor.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0