Warum kann man dem Thread kein notify senden?

Status
Nicht offen für weitere Antworten.

MichiM

Bekanntes Mitglied
Hi,

in der Vorbereitung fürs Java-Examen bin ich auf folgende Übungsfrage gestoßen, die ich mal übersetze und von den Bezeichnern her mal so bisschen abwandle - die Antworten lass ich am besten mal so, wie sie sind.

Peter arbeitet bei Firma x und entwickelt eine Applikation in Java.
Er definiert einen Monitor namens JMoni, der zehn Threads in seinem Wartepool beinhaltet.
Alle Threads haben die gleiche Priorität. Er möchte nun genau einem dieser Threads namens jThr ein notify-Signal senden, sodass jThr vom wait-Status in den ready-Status übergeht. Wie kann er das bewerkstelligen? :)


Hier die angebotenen Antworten:

a) Execute notify(jThr); statement from the synchronized code of jMoni
b) Execute jMoni.notify(jThr); statement from the synchronized code of any thread
c) Execute jMoni.notify(jThr); statement from the synchronized code of jMoni
d) Execute jMoni.notify(jThr); statement from the code of any thread
e) He cannot specify the thread to be notified.

Richtig soll e) sein und ich will auch gar nicht mal bezweifeln, dass das so ist. ;)


Aber WARUM geht das nicht? Geht das überhaupt nicht oder geht es nur nicht mit den von a) bis d) angebotenen Methoden?
Ich weiß natürlich nicht, wie jMoni.notify() konkret ausschaut - aber würde man ein synchronisiertes jThr.notify() verwenden, würde es doch anders ausschauen? Man kann doch einem Thread-Objekt von einem synchronisierten Code-Block aus ein notify-Signal schicken, indem man thr.notify() aufruft - man braucht halt die Referenz darauf - oder sehe ich das falsch? :)

Gruß Michi
 

Maximum

Aktives Mitglied
Verstehe ich das dann richtig, dass man (wenn man mehrere threads hat) entweder alle oder keinen in der ready-status überführen kann... und nur wenn man einen einzigen thread hat funzt das mit notify() ?
 

MichiM

Bekanntes Mitglied
Das ist doch z.B. von irgendeiner Stelle aus, für die thr sichtbar ist, zulässig:

Code:
		synchronized (thr)
		{
		   thr.notify();
		}


Und in diesem Thread thr sitzt dann das wait(), nach dem es weitergeht, wenn es das notify-Signal erhält:

Code:
		synchronized (this)
		{
		        try
		        {
				   wait();
				   System.out.println("genug gewartet");
		        }
		        catch (InterruptedException e)
		        {
		        }
		}

Was genau soll da nicht gehen oder versteh ich die Situation einfach falsch? :? :D
 

MichiM

Bekanntes Mitglied
Uff je :lol:, das würde ich höchstens dann verstehen, wenn mehrmals das gleiche Objekt (über die selbe Objektreferenz) von derselben Thread-Klasse angelegt und gestartet wird. M.E. geht das aber gar nicht. Man kann zwar mehrere Objekte von einer Thread-Klasse erzeugen, nicht jedoch mehr als eines davon gleichzeitig starten?
Ansonsten java.lang.IllegalThreadStateException?

Und sobald ich verschiedene Objektreferenzen verwende, kann ich die Threads doch erstens allesamt starten und zweitens dann auch gezielt ansprechen, auch per thrX.notify() ?
 

Lim_Dul

Top Contributor
notify wendest du nicht auf Threads, sondern auf beliebige Objekte an. Dies können - müssen aber nicht Threads sein.

Beispiel:

Code:
public class ThreadA extends Runnable {
 private Object semaphore;

  public ThreadA(Object o) {
    semaphore = o;
  }

  public void run() {
    snychronized(semaphore) {
      wait();
    }
    System.out.println("Hier ist Thread A");
  }
}

public class ThreadB extends Runnable {
 private Object semaphore;

  public ThreadB(Object o) {
    semaphore = o;
  }

  public void run() {
    snychronized(semaphore) {
      wait();
    }
    System.out.println("Hier ist Thread B");
  }
}

public class Test() {

  public static void main(String args[]) {
    Object o = new Object();
    new Thread(new ThreadA(o)).start();
    new Thread(new ThreadB(o)).start();
    snychronized(semaphore) {
      o.notify();
    }
  }
}

Dies geht, und es nun nicht klar, welcher der beiden Threads (A oder B) geweckt wird.

Wenn du bei jedem Thread als Semaphoren-Objekt den Thread selber nimmst, kannst du natürlich auch gezielt einzelne Threads wecken. Dann warten die aber nicht auf das gleiche Objekt.
 

MichiM

Bekanntes Mitglied
So sehr ich auch grüble, ich komm nicht dahinter, zumal ich vorhin mal Lim_Duls Beispiel bisschen umgebaut hab, sodass es möglich ist, Thread-Objekte von mehreren gestarteten gezielt anzusprechen und dementsprechend auch mit notify-Meldungen zu versorgen.


Die Thread-Klasse:
Code:
public class ThreadClass extends Thread
{
  
  Object ref;
  int count;
  boolean waitstate = false;
  
  public ThreadClass(int count)
  {
	  this.count = count;  
  }
	
  public void setReference (Object o)
  {
	  this.ref = o;
  }
  
  public boolean ready()
  {
	  return waitstate;
  }
  
  public void run()
  {
	System.out.println("Hier ist Thread Nr. " + count);
	
	synchronized (ref)
    {
      try
      {
        System.out.println("Thread " + count + " wartet nun erstmal.");
        waitstate = true;
    	wait();
    	System.out.println("Thread " + count + " macht nun weiter.");
      }
      catch (InterruptedException e)
      {
      }
    }
  }
}

Die Test-Klasse, die auch der o.g. Monitor sein könnte.
Code:
public class Test
{
    public static void main(String args[]) {
    	
    int counter = 1;    	
    
    ThreadClass c1 = new ThreadClass(counter++);
    Thread t1 = new Thread(c1);
    c1.setReference (c1);
    
    ThreadClass c2 = new ThreadClass(counter++);
    Thread t2 = new Thread(c2);
    c2.setReference (c2);
    
    t1.start();
    t2.start();
   
    while ( ! c2.ready() );
    System.out.println("Wir lassen nun zuerst Thread 2 weitermachen...");
    
    synchronized (c2)
    {
      c2.notify();
    }

    while ( ! c1.ready() );
    System.out.println("...und nun Thread 1.");
    
    synchronized (c1)
    {
      c1.notify();
    }
    
  }
}

Konsolen-Ausgabe:
Hier ist Thread Nr. 1
Thread 1 wartet nun erstmal.
Hier ist Thread Nr. 2
Thread 2 wartet nun erstmal.
Wir lassen nun zuerst Thread 2 weitermachen...
Thread 2 macht nun weiter.
...und nun Thread 1.
Thread 1 macht nun weiter.

Wo genau liegt mein Denkfehler? Ich nehm an, ich bring da was durcheinander. Was verwechsle ich? :)
 

Lim_Dul

Top Contributor
Du weist jedem Thread genau ein Objekt zu, auf das er "wartet".

Damit kannst du natürlich explizit einen Thread wecken.

Du kannst aber auch 2 verschiedenen Threads das gleiche Objekt zuweisen, auf das sie warten.
Und wenn 2 Threads auf das gleiche Objekt warten, dann kannst du nicht mehr spezifizieren, welcher Thread geweckt werden soll.

Code:
public class ThreadClass extends Thread
{
 
  Object ref;
  int count;
  boolean waitstate = false;
 
  public ThreadClass(int count)
  {
     this.count = count; 
  }
   
  public void setReference (Object o)
  {
     this.ref = o;
  }
 
  public boolean ready()
  {
     return waitstate;
  }
 
  public void run()
  {
   System.out.println("Hier ist Thread Nr. " + count);
   
   synchronized (ref)
    {
      try
      {
        System.out.println("Thread " + count + " wartet nun erstmal.");
        waitstate = true;
       wait();
       System.out.println("Thread " + count + " macht nun weiter.");
      }
      catch (InterruptedException e)
      {
      }
    }
  }
}




Code:
public class Test
{
    public static void main(String args[]) {
       
    int counter = 1;       
   
    ThreadClass c1 = new ThreadClass(counter++);
    Thread t1 = new Thread(c1);
    c1.setReference (c1);
   
    ThreadClass c2 = new ThreadClass(counter++);
    Thread t2 = new Thread(c2);
    c2.setReference (c1); // Hier setze ich Thread 2 auch Thread 1 als Referenz Objekt
   
    t1.start();
    t2.start();
   
    while ( ! c2.ready() );
    System.out.println("Wir lassen nun zuerst Thread 2 weitermachen..."); // Tja, nun kann man nicht mehr explizit sagen, dass Thread 2 weiter machen soll...
   
    synchronized (c1)
    {
      c1.notify(); // Weckt entweder Thread 1 oder Thread 2, welcher genau ist unbekannt
    }

  }
}
 

MichiM

Bekanntes Mitglied
Ich kann nicht sagen, dass ich den Unterschied zwischen unseren Beispielen nicht sehe, ich kann nur nicht behaupten, dass ich von der Aufgabenstellung zwangsläufig zu der Lösungsform komme, die durch Dein Beispiel verkörpert wird. :)

Ich denk mir einfach: "Na gut, wenn da zehn Threads individuell ansprechbar verwaltet werden sollen, dann programmier ich das ganze eben so, DASS sie verwaltet werden können..." Ich kann zumindest nicht rauslesen, dass da eine Mehrfachzuweisung wie erwähnt gefordert ist. Daran hängts bei mir. :wink:
 

Lim_Dul

Top Contributor
*klick* :)

Jetzt sehe ich dein Problem.

Klar kannst so programmieren, dass du explizit Threads wecken kannst. (Wäre auch schlimm, wenn es nicht gehen).

Du kannst nur beim Aufruf von notify nicht bestimmen, welcher geweckt wird, sondern du weißt, dass maximal einer geweckt wird, der auf dieses Monitorobjekt wait() aufgerufen hat. Wenn du aus deinem Programm her eine eindeutige Zuordnung Monitorobjekt <-> Thread hast, ist natürlich klar, welcher Thread geweckt wird. Sobald aber mehrere Threads sich ein Monitorobjekt teilen, dann geht es nicht mehr. Du musst also mit deinem Programmcode dafür sorgen, dass pro Monitorobjekt nur ein Thread existiert. Dies ist aber eine Zusatzbedingung, die nicht von notify() geliefert wird.

PS: In der Aufgabenstellung steht explizit, dass sie sich ein Monitorobjekt teilen:

Er definiert einen Monitor namens JMoni, der zehn Threads in seinem Wartepool beinhaltet.
 

MichiM

Bekanntes Mitglied
So ganz eindeutig find ich das eben nicht formuliert. Schwammige Formulierungen waren mir schon immer ein Stolperstein und werdens wohl auch immer bleiben. :) Denn wie dieser Monitor (ist ja für mich zunächst ein ziemlich abstrakter Begriff - würde der durch ein Informatikstudium evtl. konkreter? :) ) genau aufgebaut sein soll, geht für mich nicht draus hervor - ob das genau ein Objekt oder eine Objektliste oder was auch immer sein soll... Also fix is da nix, find ich. Da kann ich nur hoffen, dass bei der echten Prüfung dann genügend Aufgaben dabei sind, die nicht so viel Interpretationsspielraum bieten. :lol:
 

Lim_Dul

Top Contributor
Schonmal probiert, wait() oder notify() aufzurufen, ohne innerhalb eines entsprechenden synchronized Blocks zu sein?

Dann schmeisst dir java eine IllegalMonitorStateException

Auch interessant ist dazu die Doku von wait(), wo drinsteht:

The current thread must own this object's monitor.[/red] The thread releases ownership of this monitor[/red] and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.

This method should only be called by a thread that is the owner of this object's monitor. See the notify method for a description of the ways in which a thread can become the owner of a monitor.


In dem Zusammenhang ist immer von Monitor die Rede. Daher der implizite Schluss, dass mittels
Er definiert einen Monitor namens JMoni
nicht viel mehr als ein Objekt gemeint ist, dessen wait/notify Methoden genutzt werden.

Im Prinzip hast du Recht, man könnte sich ein Monitor Objekt so definieren, dass man damit explizite Threads wecken kann.
 

Illuvatar

Top Contributor
Ja ein Monitor ist halt immer das Objekt auf dem die wait/notify Methoden aufgerufen werden... aber wie willst du das denn bitte machen, dass ein best. Thread aufgeweckt wird?

Oder anders ausgedrückt:

Code:
public class Bla
{
  public static void main(String[] args)
  {
     final Object monitor = new Object();
     class MyThread extends Thread
     {
       public void run()
       {
         synchronized (monitor){
           try{
             monitor.wait();
           }catch (InterruptedException e){
           }
         }
         System.out.println(cnt + " runs");
         System.exit(0);
       }
       public int cnt = 0;
     };
     MyThread[] threads = new MyThread[10];
     for (int i = 0; i < 10; i++){
       threads[i] = new MyThread();
       threads[i].cnt = i;
       threads[i].start();
     }
     try{
       Thread.sleep(1000);
     }catch (InterruptedException e){
     }
     synchronized (monitor){
       //Wer eine Zeile postet, durch die die Ausgabe bei jeder Ausführung in jeder JVM etc "7 runs" ist, kriegt nen Keks
       //interrupt gilt net, da das nix damit zu tun hat :p
     }
  }
}
 

MichiM

Bekanntes Mitglied
//Wer eine Zeile postet, durch die die Ausgabe bei jeder Ausführung in jeder JVM etc "7 runs" ist, kriegt nen Keks

Das ließe sich z.B. durch diese Zeile lösen:
  • System.out.println("7 runs"); :D :applaus:

Aber nun hab ich mal paar Seiten zum Thema Monitor in diesem Zusammenhang nachgelesen, weiß nun, worum es geht und versteh die Problematik, dass mit dieser Technik keine Threads gezielt angesprochen werden können.

Was ich noch nicht herausgefunden hab: Kann man von einem Thread aus auch die gesamte Applikation beenden?

Angenommen, man baut in die Klasse Bla noch

Code:
public void ende()
  {
	  Runtime.getRuntime().exit(0);  
  }

ein und ruft .ende() auf einer in main deklarierten final-Instanz von Bla nach

Code:
System.out.println(cnt + " runs");

auf - Warum wird da auch nur wieder der Thread und nicht die gesamte Applikation beendet?
 

Illuvatar

Top Contributor
vorher.jpg


@topic
Also Runtime.getRuntime().exit(0); beendet eigentlich die ganze Application.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
V Kein neuer Thread trotz Runnable Java Basics - Anfänger-Themen 4
Leyla Thread isInterrupt Java Basics - Anfänger-Themen 18
P Meldung aus Java-Klasse in Thread an aufrufende Klasse Java Basics - Anfänger-Themen 1
A Thread XML-Dateien zusammenfügen Java Basics - Anfänger-Themen 11
F influxdb Upload in eigenem Thread Java Basics - Anfänger-Themen 2
frager2345 Thread - Methoden synchronized deklarieren Java Basics - Anfänger-Themen 10
berserkerdq2 Größter unterschied von extends thread und implements runnable? Java Basics - Anfänger-Themen 2
T Thread beenden aus zweiter Klasse Java Basics - Anfänger-Themen 4
A Thread - Synchronized Java Basics - Anfänger-Themen 10
A Thread Producer - Consumer Java Basics - Anfänger-Themen 1
A Thread-Semhapore Java Basics - Anfänger-Themen 0
A Thread Exchanger Java Basics - Anfänger-Themen 22
A Thread-Cyclicbarrier Java Basics - Anfänger-Themen 4
B In einem Thread Endlosschleife beenden Java Basics - Anfänger-Themen 19
A Thread-Verklemmung Java Basics - Anfänger-Themen 10
A Thread-Schreibe-Lese-Problem Java Basics - Anfänger-Themen 4
A Thread find number Java Basics - Anfänger-Themen 8
F Thread.sleep() Java Basics - Anfänger-Themen 5
F Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 11 at main.main(main.java:11) Java Basics - Anfänger-Themen 2
A Thread Java Basics - Anfänger-Themen 3
M Exception in thread "main" java.util.NoSuchElementException Java Basics - Anfänger-Themen 2
A Thread Java Basics - Anfänger-Themen 8
B Compiler-Fehler Fehlermeldung Exception in thread, falsche Eingabewert Java Basics - Anfänger-Themen 2
M Thread-Zustände Java Basics - Anfänger-Themen 6
CptK For-Schleife in Thread nach jedem Durchlauf pausieren Java Basics - Anfänger-Themen 35
S Kriege Fehler "Exception in thread" beim Benutzen von SubStrings. Java Basics - Anfänger-Themen 2
B Endlosschleife Thread sauber beenden Java Basics - Anfänger-Themen 19
D Java Thread wartet nur ein mal Java Basics - Anfänger-Themen 1
D Java Thread wartet nur ein mal Java Basics - Anfänger-Themen 0
O Exception in thread "main" java.lang.ArithmeticException: / by zero Java Basics - Anfänger-Themen 4
C Thread und TimerTask, Verstädnisproblem Java Basics - Anfänger-Themen 10
amgadalghabra Sorting Thread Launcher Java Basics - Anfänger-Themen 3
B Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException Java Basics - Anfänger-Themen 8
A Thread Java Basics - Anfänger-Themen 4
A Thread Java Basics - Anfänger-Themen 1
A Thread Java Basics - Anfänger-Themen 0
R Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException Java Basics - Anfänger-Themen 5
S Compiler-Fehler Exception in thread "main" java.lang.Error: Unresolved compilation problem: Java Basics - Anfänger-Themen 6
L Liste in anderem Thread laden Java Basics - Anfänger-Themen 1
B Thread / Prozess stoppen? Java Basics - Anfänger-Themen 22
I Compiler-Fehler Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5 Java Basics - Anfänger-Themen 3
B Threads Thread sleep() Method einfache Frage Java Basics - Anfänger-Themen 8
W Thread Aufgabe - Vorgehensweise Java Basics - Anfänger-Themen 8
L Liste in anderem Thread laden Java Basics - Anfänger-Themen 0
J Threads PrograssBar update während thread Java Basics - Anfänger-Themen 13
D Compiler-Fehler Wert auf Datenbank übertragen und Sleep Thread Java Basics - Anfänger-Themen 3
Spencer Reid JavaFX Memory Thread.sleep Java Basics - Anfänger-Themen 1
S Thread.sleep mit JProgressBar Java Basics - Anfänger-Themen 1
ralfb1105 Frage zu Thread Synchronisation mit wait() und notify() Java Basics - Anfänger-Themen 3
R Exception in thread "main" java.lang.NullPointerException Java Basics - Anfänger-Themen 10
J JavaFX -> SocketIO -> Thread -> Update Label Java Basics - Anfänger-Themen 13
J Thread Handling Java Basics - Anfänger-Themen 9
A Problem mit Thread.sleep Java Basics - Anfänger-Themen 4
C Thread in Methode + raus aus der Schleife Java Basics - Anfänger-Themen 10
E Threads Thread in While-Schleife nur einmal starten Java Basics - Anfänger-Themen 2
F Daten von Thread an den aufrufenden zurückgeben Java Basics - Anfänger-Themen 22
C Compiler-Fehler Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2 Java Basics - Anfänger-Themen 3
B Thread Problem Java Basics - Anfänger-Themen 7
N KeyListener in Thread Java Basics - Anfänger-Themen 0
M Thread.sleep() Funktion Java Basics - Anfänger-Themen 1
W JLabel in Main aus Thread verändern. Java Basics - Anfänger-Themen 4
D Ausgeben welcher Thread gerade Arbeitet Java Basics - Anfänger-Themen 8
N Threads Thread-Fehler Java Basics - Anfänger-Themen 2
F Thread um Uhrzeit ausführen Java Basics - Anfänger-Themen 5
F Get/Post als eigener Thread mit Rückgabe Java Basics - Anfänger-Themen 5
J Exception in thread "main" Java Basics - Anfänger-Themen 1
F Thread der auf eine Queue wartet, sicher beenden Java Basics - Anfänger-Themen 4
B Animation mit Thread(s) Java Basics - Anfänger-Themen 23
I Thread.sleep (1000); Java Basics - Anfänger-Themen 1
M Threads Jede Klasse einem Thread zuweisen Java Basics - Anfänger-Themen 7
J Java Thread cancel() und wiederbeleben Java Basics - Anfänger-Themen 4
J BouncingBalls 1 Thread Java Basics - Anfänger-Themen 3
L Fehler: Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException Java Basics - Anfänger-Themen 4
J Timer oder Thread programmieren ? Java Basics - Anfänger-Themen 10
fLooojava Laufender Thread | Boolean ändern Java Basics - Anfänger-Themen 9
T Thread Pool mit Work Stealing Java Basics - Anfänger-Themen 1
R Java Thread Java Basics - Anfänger-Themen 10
J Welche Methoden laufen im neuen thread ?? Java Basics - Anfänger-Themen 9
S Java memory fehler: Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap spa Java Basics - Anfänger-Themen 5
K Thread - Methoden in die run Methode Schreiben Java Basics - Anfänger-Themen 5
N Threads Exception in thread "main"... Feher bei dem Versuch ein Radius zu berechnen Java Basics - Anfänger-Themen 4
A Code läuft nicht, Fehlermeldung Exception in thread "main" java.lang.Error: Unresolved compilation " Java Basics - Anfänger-Themen 11
V Threads Exception in Thread behandeln Java Basics - Anfänger-Themen 3
S Methoden Multi-Thread und Methoden Objects. Java Basics - Anfänger-Themen 1
J Thread erstellen (BlueJ Projekt) Java Basics - Anfänger-Themen 3
P Exception in thread "main" java.lang.NoClassDefFoundError: Java Basics - Anfänger-Themen 1
F Threads Variable aus einem Thread in main Methode? Java Basics - Anfänger-Themen 9
K Exception in thread "main" Java Basics - Anfänger-Themen 7
L Thread-Frage Java Basics - Anfänger-Themen 2
E Was ist ein idle-thread? Java Basics - Anfänger-Themen 1
D Exception in thread "AWT-EventQueue-0" Java Basics - Anfänger-Themen 8
J Threads Prozess in Thread auslagern Java Basics - Anfänger-Themen 2
G Thread mehrmals starten und schliessen Java Basics - Anfänger-Themen 6
F Thread Koordination (Vorteile/Nachteile) Java Basics - Anfänger-Themen 0
O Thread aus dem Thread stoppen Java Basics - Anfänger-Themen 6
O Swingworker/Thread Java Basics - Anfänger-Themen 3
R Focus auf JPanel im Thread Java Basics - Anfänger-Themen 9
S musik in eigenem thread Java Basics - Anfänger-Themen 2
A Klasse,Vererbung,Interface,Singleton,Thread Java Basics - Anfänger-Themen 5
IngoF GUI mit Thread Daten austauschen. Java Basics - Anfänger-Themen 6

Ähnliche Java Themen

Neue Themen


Oben