Watki, wait() i notifyAll()

0

Witam, mam taki kawalek kodu:

package test;

//--------------------

class Randezvous {

    public synchronized youWillWait() {
        try {
            wait();
        } catch (InterruptedException exc) {}
    }

    public synchronized void notifyAllWaiters() {
        notifyAll();
    }

}

//--------------------

class Waiter extends Thread {

    private Randezvous rv;
    private static int waitersCount;
    private int serialNo;

    public Waiter(Randezvous r) {
        rv = r;
        serialNo = waitersCount;
        ++waitersCount;
    }

    public void run() {
        rv.youWillWait();
        System.out.println("Waiter #" + serialNo + " notified!");
    }
    
}

//--------------------

public class Main {

    public static void main(String[] args) {
        Randezvous rand = new Randezvous();
        Waiter w0 = new Waiter(rand);
        w0.start();
        Waiter w1 = new Waiter(rand);
        w1.start();
        Waiter w2 = new Waiter(rand);
        w2.start();
        rand.notifyAllWaiters();
    }

}

Powinien on uruchomic 3 watki, zaraz po tym one sa usypiane za pomoca wait() w obiekcie klasy Randezvous. Zaraz po utworzeniu 3 watkow i uspieniu ich, wywoluje metode notifyAll(). Powinny chyba zostac wypisane na ekran wiadomosci od poszczegolnych watkow (patrz metoda run()), natomist program nic nie wypisuje i co gorsza chyba sie wiesza. Czy ktos moze mi w tym pomoc?

0
Ali G napisał(a)
//...
    public static void main(String[] args) {
        Randezvous rand = new Randezvous();
        Waiter w0 = new Waiter(rand);
        w0.start();
        Waiter w1 = new Waiter(rand);
        w1.start();
        Waiter w2 = new Waiter(rand);
        w2.start();
        rand.notifyAllWaiters();
    }
}

Powinien on uruchomic 3 watki, zaraz po tym one sa usypiane za pomoca wait() w obiekcie klasy Randezvous. Zaraz po utworzeniu 3 watkow i uspieniu ich, wywoluje metode notifyAll(). Powinny chyba zostac wypisane na ekran wiadomosci od poszczegolnych watkow (patrz metoda run()), natomist program nic nie wypisuje i co gorsza chyba sie wiesza. Czy ktos moze mi w tym pomoc?

E no, nie tak szybko :) Daj trochę czasu runtime'owi :)

//...
       w2.start();
        
        try{
            Thread.currentThread().sleep(2000);
        } catch (InterruptedException ie){}

        synchronized (rand) {
            rand.notifyAllWaiters();
        }
//...
0

Teraz wszystko dziala, dzieki. Moze wytlumaczysz mi dlaczego musialem uspic watek? Bo nie rozumiem tu czegos...

0

Od momentu uruchomienia wątku do tego, że on naprawdę zostanie uruchomiony zazwyczaj mija trochę czasu (runtime Javy musi wykonać kilka rzeczy, system operacyjny też się trochę napracuje). Poza tym tak naprawdę czas procesora jest dzielony między wątki i to, że wywołałeś metodę start() nie znaczy, że wątek dostał czas na swoje wykonanie (zmienił się tylko jego stan na 'tak, teraz mogę się już wykonać').
Poczytaj tutorial o wątkach, mimo, że to jest Java, to nie oznacza, że jest to proste. [a co w Javie jest proste? haha [diabel] ]

http://java.sun.com/docs/books/tutorial/essential/threads/lifecycle.html

After the start method has returned, the thread is "running." Yet, it's somewhat more complex than that. As the previous figure shows, a thread that has been started is in the Runnable state. Many computers have a single processor, thus making it impossible to run all "running" threads at the same time. The Java runtime system must implement a scheduling scheme that shares the processor among all "running" threads. (See Thread Scheduling for more information about scheduling.) So at any given time, a "running" thread may be waiting for its turn in the CPU.

Proste, nie? :)

0

Tak, proste :) ale wiedzialem o tym juz wczesniej. Czego nie wiem nadal to fakt dlaczego moj poprzedni kod po uruchomieniu i pozostawieniu na kilka minut nie wykazywal zadnych oznak funkcjonoania zgodnie z zalozeniami (moimi ;P )
Chyba ze mozna to wytlumaczyc w ten sposob ze wszystkie watki byly gotowe do startu, a metoda notifyAllWaiters() byla faktycznie wywolala zanim watki doszly do wykonania metody wait(). Z tego wynika ze zawiesilem swoj program?

Co do prostoty, niedawno mialem okazje pomagac koledze pisac program w MFC na zaliczenie semestru z OOP. Mialem do zrobienia wiele rzeczy, miedzy innymi jakis tam watek dodac. No i nie powiesz mi (zakadam ze znasz MFC) ze to rzutowanie LPVOID na wskaznik do parametru jaki chcesz wykorzystac jest latwiejsze i przyjemniejsze niz watki w Javie?

W kazdym badz razie wielkie dzieki za odzew!

0
Ali G napisał(a)

Chyba ze mozna to wytlumaczyc w ten sposob ze wszystkie watki byly gotowe do startu, a metoda notifyAllWaiters() byla faktycznie wywolala zanim watki doszly do wykonania metody wait(). Z tego wynika ze zawiesilem swoj program?

Prosta zwiecha. Czekanie (bez limitu czasu) na coś, co już sie stało.

Z prostotą chodziło mi o fałszywe poczucie, że w Javie można wszystko zrobić jak się chce i nie zwracać na nic uwagi :>
Nawet mi nie mów o MFC... Ale zawsze można to ładnie obudować w (prawdziwie) obiektowy sposób :)

Powodzenia z (wszelkimi) wątkami.

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