Deadlock-nie rozumiem czemu powsta?

0

Wiem ze ten temat byl tutaj juz poruszany http://4programmers.net/Forum/Java/235550-deadlock_-_dlaczego Natomiast odpowiedz __krzysiek85 jest dla mnie nie zrozumiala. Wrzuce jeszcze raz kod tutaj

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

I teraz czemu tutaj niby te dwa watki sie wzajemnie blokuja mi sie wydawalo ze jezeli np. Alphonse zacznie sie wykonywac to zalozy blokade i do momentu az nie skonczy wykonywac bowBack tej blokady nie odda i dopiero wtedy Gaston bedzie mogl dzialac.Ale tak nie jest, w poscie do ktorego wrzucilem link __krzysiek85 pisze o dwoch monitorach do ktorych dostep musza uzyskac watki ale czemu, gdzie jest drugi?

Z gory dzieki za wszelkie odpowiedzi

0

Chyba juz wiem to sie bierze stad : alphonse.bow(gaston) i gaston.bow(alphonse) i z tego ze w metodzie bow jest
bower.bowBack(this); czyli np dla alphonse.bow(gaston) bower==gaston a na ten obiekt moze byc juz zalozona blokada przez drugi watek. Dobrze mysle?

A tutaj jeszcze poprawiony przeze mnie kod, ktory zapobiega powstawaniu zakleszczenia

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");
		final Thread t = new Thread(new Runnable() {
			public void run() {
				alphonse.bow(gaston);
			}
		});
		t.start();
		Thread t2 = new Thread(new Runnable() {
			public void run() {
				try {
					t.join();
					gaston.bow(alphonse);
				} catch (InterruptedException ex) {
					System.out.println("Mam cie");
				}
			}
		});
		t2.start();
	}
}

Jesli ktos by mogl tez rzucic okiem czy to jest ok, to by bylo super:)

1

One nie tyle wzajemnie się blokują, co mogą wzajemnie się blokować (w tym przykładzie raczej tak się stanie). Dzieje się tak wtedy, gdy oba wątki są w metodach bow().
Na początku musisz wiedzieć, że jeśli używasz zapisu typu:

public synchronized void metoda() { 
    foo(); 
}

To jest to równoznaczne z zapisem:

public void metoda() {
    synchronized(this) {
        foo();
    }
}

Czyli lockiem jest domyślnie obiekt, w którym wywoływana jest metoda.

Teraz opiszę, jak powstaje deadlock:

  • Wątek 1 wchodzi do metody bow() obiektu alphonse i (jako że metoda jest synchronizowana) trzyma locka w postaci obiektu alphonse.
  • Wątek 2 wchodzi do metody bow() obiektu gaston i trzyma locka w postaci obiektu gaston.
  • Wątek 1 próbuje wywołać metodę bowBack() z obiektu gaston, więc musi być w posiadaniu locka (czyli obiektu gaston), ale nie może go dostać, bo trzyma go obecnie wątek 2, więc wątek 1 czeka.
  • Wątek 2 próbuje wywołać metodę bowBack() z obiektu alphonse, ale nie może, bo trzyma go wątek 1.
    Bum - oba wątki stoją.

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