wait notify - watki

0

Witam, powiedzmy że mamy poniższą definicję klasy reprezentującą wątki:

private  int thread_id; 

public MyThread(int id)
   {
         this.thread_id = id;
    }

    public int getThread_ID() 
    {
        return thread_id;
    }

    public void setThread_ID(int n) 
    {
        this.thread_id = n;
    }

@Override
    public void run() 
    { 

       System.out.println("ID" + thread_id)

     }

Tworząc sobie w klasie main wątki : w1(1) , w2(2) , w3(3) , w4(4) , w5(5) wywołując metodę start() wątki oczywiście wykonują się "jak chcą" ponieważ nie są zsynchronizowane. Mogę użyć samego synchronized , ale chciałbym zgłębić zagadnienia notify i wait. Czy moglibyście pokazać mi na przykładzie - powiedzmy - by najpierw wykonały się wątki, których reszta z dzielenia ich id przez 2 jest równa zero? Czyli w teorii pierwsze powinny się wykonać wątki w2 i w4 a dopiero później w1, w3 i w5. Sam problem oczywiście mogę rozwiazać na przykład za pomocą sleepa i dodatkowych instrukcji warunkowych, ale chodzi mi o podejście do tego tematu z użyciem wcześniej wspomnianych notify i wait. Z góry dzięki!

1

Przykład z kompendium Herberta Schildta

Listing 11.
// Wstrzymywanie i wznawianie wątku w nowoczesny sposób.
class NewThread implements Runnable {
  String name; // nazwa wątku
  Thread t;
  boolean suspendFlag;

  NewThread(String threadname) {
    name = threadname;
    t = new Thread(this, name);
    System.out.println("Nowy wątek: " + t);
    suspendFlag = false;
    t.start(); // Uruchamia wątek
  }

  // To jest punkt startowy wątku.
  public void run() {
    try {
      for(int i = 15; i > 0; i--) {
        System.out.println(name + ": " + i);
        Thread.sleep(200);
        synchronized(this) {
          while(suspendFlag) {
            wait();
          }
        }
      }
    } catch (InterruptedException e) {
      System.out.println(name + " został przerwany");
    }

    System.out.println("Wyjœcie z wątku " + name);
  }

  synchronized void mysuspend() {
    suspendFlag = true;
  }

  synchronized void myresume() {
    suspendFlag = false;
    notify();
  }
}

class SuspendResume {
  public static void main(String args[]) {
    NewThread ob1 = new NewThread("Jeden");
    NewThread ob2 = new NewThread("Dwa");

    try {
      Thread.sleep(1000);
      ob1.mysuspend();
      System.out.println("Zawieszenie wątku Jeden");
      Thread.sleep(1000);
      ob1.myresume();
      System.out.println("Wznowienie wątku Jeden");
      ob2.mysuspend();
      System.out.println("Zawieszenie wątku Dwa");
      Thread.sleep(1000);
      ob2.myresume();
      System.out.println("Wznowienie wątku Dwa");
    } catch (InterruptedException e) {
      System.out.println("Przerwanie wątku głównego");
    }

    // oczekuje na zakończenie wątków
    try {
      System.out.println("Oczekiwanie na zakończenie wątków.");
      ob1.t.join();
      ob2.t.join();
    } catch (InterruptedException e) {
      System.out.println("Przerwanie wątku głównego");
    }

    System.out.println("Koniec wątku głównego.");
  }
}

To jest taki mały przykład wielowątkowości z użyciem wait i notify. Może jakoś pomoże Ci ugryźć temat.
Dodatkowo ten link na blogu oraz link z ProgramCreek
Jeszcze mała uwaga na SO

0

Dzięki za odpowiedź, na pewno skorzystam, ale wolałbym na początek spojrzeć na spokojnie na kawałku kodu , który podałem. Będzie ktoś tak dobry i pokaże to na przykładzie o który prosiłem? Z góry dzięki.

0

Ten przykład, który sobie wymyśliłeś nie jest wg mnie dobry zobrazowania wait/notify. Wait/notify używamy gdy jakiś wątek ma do wykonania zadanie na pewnym obiekcie, ale nie może go z pewnych względów wykonać, więc przechodzi w stan czekania (a nie gaśnie całkowicie po wyświetleniu swojego ID jak u ciebie), aby nie blokować innych wątków. Gdy zadanie stanie się możliwe do wykonania i tym samym dostanie sygnał notify to wraca do akcji. To co sobie wymyśliłeś to można na jakimś isAlive() albo join() oprzeć. Chyba, że się mylę to mnie poprawcie.

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