Interthread-Kommunikation

delphinis

Mitglied
Hallo,
versuche verzweifelt eine Interthread-Kommunikation hinzukriegen. Dazu hab ich mein Programm auf das nötigste Reduziert.
- Hauptprogramm mit zwei Threads
- Der eine Thread schickt dem zweiten alle 5 Sekunden ein Notify
- Der zweite meldet dies dem User
- alles ist über ein Object obj synchronisiert
Das nachfolgende Programm ist lauffähig.

Problem:
Beide Threads arbeiten, aber der zweite Thread reagiert nicht mit wait() auf das notify des anderen.

Java:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;

public class ThreadTest extends JPanel implements ActionListener {
  private static final long     serialVersionUID = 1L;
  JPanel 												topPanel;
  JButton                       testButton;
  String                        programname      = "ThreadTest";
  static JFrame                 frame;
  JTextArea                     logTextArea;
  JScrollPane 									logTextAreaScrollPane;

  Object obj = new LogData();
  Thread timeThread;
  Thread receiveThread;
  
  public static void main(String[] args) {
    frame = new JFrame(); // Frame = Window
    frame.setBounds(1920, 0, 600, 1200);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(new ThreadTest());
    frame.setVisible(true);
  }

  public ThreadTest() {
  	try {
  		frame.setTitle(programname);
      // **************************************************************************************************
      // GUI BEGIN
      // **************************************************************************************************
      try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
      } catch (Exception e) {}
      topPanel = new JPanel();
      frame.add(topPanel);
      this.add(topPanel, BorderLayout.NORTH);
      
      topPanel.paintAll(this.getGraphics());

      testButton = new JButton("Send");
      testButton.setBounds(20, 20, 95, 22);
      topPanel.add(testButton);
      testButton.addActionListener(this);
            
      receiveThread = new Thread(new ReceiceThread());
      receiveThread.start();
    	try {
    		Thread.sleep(300);
    	} catch (InterruptedException e) {
    		JOptionPane.showMessageDialog(frame.getRootPane(), e.getMessage());
    	}
      timeThread = new Thread(new TimeThread());
      timeThread.start();
    } catch (RuntimeException runtimeExeption) {
      runtimeExeption.printStackTrace();
      JOptionPane.showMessageDialog(this.getRootPane(), "Runtime exception:" + runtimeExeption.getMessage());
    }
  }
  
  public void actionPerformed(ActionEvent event) {
    String cmd = event.getActionCommand();
    if (cmd.equals("Send")) {
    }
  }
  
  class TimeThread implements Runnable {
    @Override public void run() {
      while (true) {
      	synchronized(obj) {
	      	try {
	      		Thread.sleep(5000);
	      		obj.notify();
	      	} catch (InterruptedException e) {
	      		JOptionPane.showMessageDialog(frame.getRootPane(), e.getMessage());
	      	}
      	}
      }
    }
  }
  
  class ReceiceThread implements Runnable {    
    @Override public void run() {
      while (true) {
      	synchronized(obj) {
	      	try {
	      		obj.wait();
		      	java.awt.Toolkit.getDefaultToolkit().beep();

	      		JOptionPane.showMessageDialog(frame.getRootPane(), "Meldung erhalten");
	      	} catch (InterruptedException e) {
	      		JOptionPane.showMessageDialog(frame.getRootPane(), e.getMessage());
	      	}
	      }
    	}
    }
  }  
  
}

Vielen Dank zum Voraus

PS: Kann man mit Notify auch einen Wert oder ein Objekt mitsenden?
 

delphinis

Mitglied
Hallo Barista,
Vielen Dank.
Ja, stimmt, der Thread wird (zeitweise) geweckt. Dies ist mir nicht aufgefallen, da es offenbar eine (sehr) unbestimmte Zeit dauert, bis der Thread auf das notify reagiert. (notify wird wie erwartet alle 5 Sekunden ausgeführt, aber der andere Thread erwacht nur sporadisch)
Zum testen hab ich nach dem notif() noch ein Beep reingetan um zu sehen, wann er dort durchfährt.
Bei mir jedenfalls kommt das Fenster nicht bei jedem notify und fünf Sekunden sollten selbst für Windows reichen ;-)?
Wie funktioniert das bei dir???

PS: Sorry an alle, die das Programmfenster vergebens gesucht haben. Zeile 27 müsste man folgendermassen ändern:
Java:
frame.setBounds(0, 0, 600, 600);
 

Barista

Top Contributor
Wie funktioniert das bei dir???

Du hast etwas zu hohe Erwartungen an mich,
ich habe Dein Prog nicht bei mir lokal eingerichtet.

Ich beantworte nur die Frage, mache aber nicht Deinen Kram fertig.

Du kannst auch mal notifyAll versuchen.
 
Zuletzt bearbeitet:

delphinis

Mitglied
Sorry, ich wollte dich nicht nötigen.
Bei diesem Problem steh ich halt auf dem Schlauch, weil es theoretisch funktionieren sollte (was du mir ja auch bestätigt hast), es praktisch aber halt nicht wirklich zu funktionieren scheint...

NotifyAll hat leider auch nichts gebracht. Denke, dies ist bei einem zu benachrichtigenden Thread funktionell ja wohl auch nichts anderes.
 
Zuletzt bearbeitet:

delphinis

Mitglied
OK, hätt mich zwar schon interessiert wieso's mit notify nicht lief aber ich hab's jetzt mit einer SynchronousQueue hingebracht. Nachdem ich auch beide Threads zuerst kreiert hab und dann erst gestartet, läuft es wie gewollt.
Für dijenigen die's interessiert, nachstehend noch den Code.

Danke für deine Hilfe, Barista

Java:
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.SynchronousQueue;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;

public class ThreadQueueTest extends JPanel implements ActionListener {
  private static final long     serialVersionUID = 1L;
  JPanel 												topPanel;
  JButton                       testButton;
  String                        programname      = "ThreadTest";
  static JFrame                 frame;
  JTextArea                     logTextArea;
  JScrollPane 									logTextAreaScrollPane;

  Object obj = new Object();
  Thread timeThread;
  Thread receiveThread;
  SynchronousQueue<Integer> queue = new SynchronousQueue<Integer>();
  
  public static void main(String[] args) {
    frame = new JFrame(); // Frame = Window
    frame.setBounds(0, 0, 600, 600);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(new ThreadQueueTest());
    frame.setVisible(true);
  }

  public ThreadQueueTest() {
  	try {
  		frame.setTitle(programname);
      // **************************************************************************************************
      // GUI BEGIN
      // **************************************************************************************************
      try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
      } catch (Exception e) {}
      topPanel = new JPanel();
      frame.add(topPanel);
      this.add(topPanel, BorderLayout.NORTH);
      System.out.println(queue.size());

      
      topPanel.paintAll(this.getGraphics());

      testButton = new JButton("Send");
      testButton.setBounds(20, 20, 95, 22);
      topPanel.add(testButton);
      testButton.addActionListener(this);
            
/*    	try {
    		Thread.sleep(300);
    	} catch (InterruptedException e) {
    		JOptionPane.showMessageDialog(frame.getRootPane(), e.getMessage());
    	}*/
      timeThread = new Thread(new TimeThread());
      
      receiveThread = new Thread(new ReceiceThread());
      timeThread.start();
      receiveThread.start();
    } catch (RuntimeException runtimeExeption) {
      runtimeExeption.printStackTrace();
      JOptionPane.showMessageDialog(this.getRootPane(), "Runtime exception:" + runtimeExeption.getMessage());
    }
  }
  
  public void actionPerformed(ActionEvent event) {
    String cmd = event.getActionCommand();
    if (cmd.equals("Send")) {
    }
  }
  
  class TimeThread implements Runnable {
  	Integer i = 0;
    @Override public void run() {
      while (true) {
	      	try {
      	synchronized(receiveThread) {
	      		System.out.println("sleep\n");
	      		Thread.sleep(5000);
	      		System.out.println("awaken");
	      		queue.put(i);
//	      		receiveThread.notify();
//	      		java.awt.Toolkit.getDefaultToolkit().beep();
      	}
	      	} catch (InterruptedException e) {
	      		JOptionPane.showMessageDialog(frame.getRootPane(), e.getMessage());
	      	}
      	i++;
      }
    }
  }
  
  class ReceiceThread implements Runnable {
    @Override public void run() {
    	Integer i;
      while (true) {
	      	try {
      	synchronized(this) {
	      		i = (Integer)queue.take();
//	      		this.wait();
		      	java.awt.Toolkit.getDefaultToolkit().beep();

	      		JOptionPane.showMessageDialog(frame.getRootPane(), "Queue element Nr. " + i.toString());
    	}
	      	} catch (InterruptedException e) {
	      		JOptionPane.showMessageDialog(frame.getRootPane(), e.getMessage());
	      	}
	      }
    }
  }  
  
}
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
CptK Backpropagation parallelisieren: Kommunikation zwischen den Threads Allgemeine Java-Themen 7
L Kommunikation zwischen C# und Java? Allgemeine Java-Themen 5
R PIPE Kommunikation mit Prozess blockiert Allgemeine Java-Themen 0
M Checksummenprüfung bei Client Server kommunikation Allgemeine Java-Themen 3
S Threads Kommunikation zwischen SocketThread und WorkerThread Allgemeine Java-Themen 11
0 Lösungsweg Client Server Kommunikation Fehlermeldung ausgeben Allgemeine Java-Themen 12
L Software-Design: Kommunikation mit SerialPort (RXTX) Allgemeine Java-Themen 2
F Serielle Kommunikation Allgemeine Java-Themen 20
A Kommunikation zwischen 2 Jar-dateien Allgemeine Java-Themen 16
S Kommunikation von Core und GUI über Schnittstellen Allgemeine Java-Themen 2
P Komponenten kommunikation Allgemeine Java-Themen 7
L Serielle Kommunikation Allgemeine Java-Themen 6
G Implementierung einer Kommunikation Allgemeine Java-Themen 7
B SerialPort Kommunikation - Pufferüberlauf Allgemeine Java-Themen 6
0 Sandbox und Applet Kommunikation Allgemeine Java-Themen 9
E kommunikation zwischen Fenstern Allgemeine Java-Themen 3
H Java C++ Interprozess Kommunikation Allgemeine Java-Themen 7
D Klassen Kommunikation Allgemeine Java-Themen 11
M Applet Servlet Kommunikation ein Problem bei externem Server Allgemeine Java-Themen 3
F Kommunikation zw 2 Java-Programmen mit unterschiedl Compiler Allgemeine Java-Themen 13
G Kommunikation mit Remotegeräten Allgemeine Java-Themen 2
A Kommunikation zwischen C++ und Java-Programm Allgemeine Java-Themen 4
J Kommunikation mit USB Gerät, das Midi-Signale sendet Allgemeine Java-Themen 4
G Kommunikation mit der seriellen Schnittstelle Allgemeine Java-Themen 6
H Kommunikation mit einem c-Prozess funzt nicht richtig Allgemeine Java-Themen 5
C Pattern für Kommunikation gesucht Allgemeine Java-Themen 3
B Kommunikation mit entferntem Thread Allgemeine Java-Themen 6
O kommunikation zw. objekten Allgemeine Java-Themen 7
G Kommunikation von zwei Java-Programmen Allgemeine Java-Themen 3
N Inter-Thread-Kommunikation Allgemeine Java-Themen 3
M Kommunikation mit externem Programm ueber Linux-Pipes Allgemeine Java-Themen 4
M Kommunikation zwischen 2 Programmen Allgemeine Java-Themen 7
G Kommunikation zwischen Threads und Gui Allgemeine Java-Themen 2
T Kommunikation mit batch datei Allgemeine Java-Themen 3
P kommunikation zwischen dialog und threads Allgemeine Java-Themen 4
K MVC - Kommunikation Controller <> Gui Allgemeine Java-Themen 5
P Kommunikation von Threads Allgemeine Java-Themen 5
V Kommunikation zwischen Programmen und Threads Allgemeine Java-Themen 7
H Servlet/Applet Kommunikation Allgemeine Java-Themen 2
C Kommunikation mit USB Port Allgemeine Java-Themen 1

Ähnliche Java Themen

Neue Themen


Oben