Merkwürdiges Thread-Verhalten

twabuzi

Mitglied
Guten Abend,
mein erweitertes jPanel soll verschiedene Rechtecke zeichnen, die in einer Warteschlange eingefügt und im 50-Millisekunden-Takt abgearbeitet werden. Damit andere Komponenten noch reagieren, wenn Thread.sleep (50) ausgeführt wird, benutze ich mehrere Threads.
Folgender Code ergab sich bisher:
Java:
public void run() {
      System.out.println("Starte Panel-Thread");
      while( true) {
        //BesondereStelle
         try {
            if (stapelToDo.size() > 0){
               System.out.println("Konfiguration wird gezeichnet!");
              
               this.zl_aktuell = this.stapelToDo.get( 0);
               this.stapelToDo.remove( 0);

               repaint();
              
               System.out.println("Verbleibende Konfigurationen: " + this.stapelToDo.size());

               Thread.sleep( 50);
            }
         } catch (InterruptedException ex) {}
      }
   }

Leider funktioniert das Ganze irgendwie nur sehr seltsam und zwar, wenn ich im Code an der Stelle "BesondereStelle" ein System.out.println("") einfüge. Was läuft hier schief?
 

DrZoidberg

Top Contributor
Ein komplettes lauffähiges Beispiel wäre schön.
Handelt es sich bei "stapelToDo" um eine Threadsichere Liste? z.B. "ConcurrentLinkedQueue"?
Wurde "zl_aktuell" als volatile deklariert oder besser noch als "AtomicReference"?
 

Thallius

Top Contributor
Das ganze ergibt doch überhaupt keinen Sinn. Mit einer Schleife mit einem repaint() und einem sleep(50) erreichst du alles aber bestimmt nicht, dass alle 50ms etwas gezeichnet wird.

Warum überhaupt alle 50ms die Queue polllen obwohl du nicht einmal weist ob überhaupt was Neues drin ist? Was wenn in den letzen 50ms zwei Einträge in die Queue eingetragen wurden?

Wie bereits von meinem Vorschreiber angesprochen. Wenn du in dem Thread etwas aus der Queue entfernst, was man eigentlich niemals machen sollte, dann musst du die Queue threadsave machen. Ich glaube kaum das du das gemacht hast...

Sag einfach mal was du genau vorhast und was das Ergebnis sein soll. Da sollte ganz bestimmt ein komplett anderes Konzept her....

Gruß

Claus
 

twabuzi

Mitglied
Guten Morgen. Wie ich bereits geschrieben habe, funktioniert mein Programm so wie ich es mir wünsche, bis auf das eingangs beschriebene Verhalten.
Als Neuling in Bezug auf Threads danke ich dir, DrZoidberg, für die Schlagworte. Das wird mir helfen, mich weiter einzulesen.
 

twabuzi

Mitglied
Ok. Nachdem ich verschiedene Anweisungen in synchronized-Methoden ausgelagert habe (immer dann, wenn eine Variable beschrieben wird) erhalte ich wieder den gleichen Fehler. An der ??-Stelle funktioniert die if-Anweisung nur, wenn ich ein Konsolenausgabe einbaue. Nur dann werden die weiteren Anweisungen ausgeführt. Warum? Hier mein kompletter Code.
Java:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.Vector;

public class SortSearchPanel extends JPanel implements Runnable{
   /*Ein spezielles Panel, das Zahl-Highlight Paare speichert. Dieses kann genutzt
   werden, um Sortier- und Suchalgorithmen zu veranschaulichen.
 
   Verwendung:
   zeichne( int[] tmp_zahlen, boolean[] tmp_highlight )
   Es werden in zwei gleichgroßen Arrays, zum einen die Zahlen, zum anderen die
   Stellen übergeben, an denen die Zahlen hervorgehoben sein sollen.
 
   setIntervall( int millisek)
   Wird die Methode "zeichne" mehrfach hintereinander aufgerufen (z.B. in einer
   Schleife), werden die verschiedenen Übergaben im Abstand einer gewisser Zeit
   gezeichnet. Dieses Intervall kann über setIntervall( int millisek) eingestellt werden.
   */

   private Vector stapelToDo = new Vector();
   private Vector zl_aktuell = new Vector();
 
   private int intervall = 50;
 
   private boolean laufend = false;

   public SortSearchPanel(){    
      Thread t = new Thread(this);
      t.start();
   }

   public void setIntervall( int millisek) {
      this.intervall = millisek;
   }
 
   private synchronized void addKonfiguration( Vector z){
      this.stapelToDo.add( z);
      System.out.println("Neue Konfiguration zum Zeichnen! (Anzahl ingesamt: " + this.stapelToDo.size() + ")");
   }

   public boolean addZahlen( int[] tmp_zahlen, boolean[] tmp_highlight ) {
      if ( tmp_zahlen.length != tmp_highlight.length) {
         return false;
      }
    
      //Übergabe in Zahlenliste zl_tmp einlesen
      Vector zl_tmp = new Vector();
      Zahl tmp_zahl = new Zahl();
    
      for (int i=0; i < tmp_zahlen.length; i++){
         tmp_zahl = new Zahl();
         tmp_zahl.wert = tmp_zahlen[i];
         tmp_zahl.highlight = tmp_highlight[i];
         zl_tmp.add( tmp_zahl);
      }
    
      addKonfiguration( zl_tmp);
      return true;
   }
 
   private synchronized void ladeAktuell() {
      //Methode, die aus dem ToDo-Stapel der zu zeichnenden Konfigurationen
      //die älteste herausnimmt und in zl_aktuell abspeichert.
    
      if ( this.stapelToDo.size() > 0) {
         this.zl_aktuell = (Vector) this.stapelToDo.get( 0);
         this.stapelToDo.remove( 0);
      }
   }
 
   public void run() {
      System.out.println("Starte Panel-Thread");

      while( true) {
         if ( this.laufend) {
            try {
               if (this.stapelToDo.size()>0 ){
                  System.out.println("Konfiguration wird gezeichnet!");
                
                  this.ladeAktuell();
                  repaint();
                
                  System.out.println("Verbleibende Konfigurationen: " + this.stapelToDo.size());

                  Thread.sleep( this.intervall);
               }
            } catch (InterruptedException ex) {}
       
         //??
         } else {
            System.out.println("laufend steht auf false");
         }
      }
   }
 
   public void start() {
      System.out.println("Zeichenprozess starten");
      this.laufend = true;
   }
 
   public void stop() {
      this.laufend = false;    
   }
 
   private synchronized boolean zeichneKonfiguration( Graphics g, Vector zl_aktuell_tmp, int breite, int hoehe){
      if (breite == 0 || hoehe == 0){
         return false;
      }

      int balkenbreite = breite / zl_aktuell_tmp.size();
    
      for ( int i = 0; i< this.zl_aktuell.size(); i++){
         Zahl z_tmp = (Zahl) zl_aktuell_tmp.get( i);
       
         if ( z_tmp.highlight) {
            g.setColor(Color.red);
         } else {
            g.setColor(Color.black);
         }
       
         g.fillRect(i*balkenbreite, hoehe-1-z_tmp.wert, balkenbreite, z_tmp.wert); 
      }
      return true;
   }
 
   public void paintComponent( Graphics g){ 
      g.setColor(Color.white);
      g.fillRect(0, 0, this.getWidth(), this.getHeight());
    
      if (this.zl_aktuell.size() > 0) {
         //zl_aktuell ist nicht leer - es gibt also etwas zu zeichnen
         if ( !zeichneKonfiguration( g, this.zl_aktuell, this.getWidth(), this.getHeight())){
            System.out.println("Fehler beim Zeichnen");          
         }
      }
   }
}
 

DrZoidberg

Top Contributor
Ich habe da mal ein lauffähiges Beispiel draus gemacht. Und es scheint zu funktionieren. Übrigens weiss ich immer noch nicht was für ein Fehler bei dir auftritt.
Java:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.Vector;
import java.util.Random;

public class SortSearchPanel extends JPanel implements Runnable {
  class Zahl {
    int wert;
    boolean highlight;
  }
 
   private Vector<Vector<Zahl>> stapelToDo = new Vector<>();
   private Vector<Zahl> zl_aktuell = new Vector<>();
   private int intervall = 50;
   private volatile boolean laufend = false;

   public void setIntervall( int millisek) {
      this.intervall = millisek;
   }
   private synchronized void addKonfiguration( Vector<Zahl> z){
      this.stapelToDo.add( z);
      System.out.println("Neue Konfiguration zum Zeichnen! (Anzahl ingesamt: " + this.stapelToDo.size() + ")");
   }

   public boolean addZahlen( int[] tmp_zahlen, boolean[] tmp_highlight ) {
      if ( tmp_zahlen.length != tmp_highlight.length) {
         return false;
      }
     
      Vector<Zahl> zl_tmp = new Vector<>();
      Zahl tmp_zahl = new Zahl();
   
      for (int i=0; i < tmp_zahlen.length; i++){
         tmp_zahl = new Zahl();
         tmp_zahl.wert = tmp_zahlen[i];
         tmp_zahl.highlight = tmp_highlight[i];
         zl_tmp.add( tmp_zahl);
      }
   
      addKonfiguration( zl_tmp);
      return true;
   }
   private synchronized void ladeAktuell() {
      if ( this.stapelToDo.size() > 0) {
         this.zl_aktuell = (Vector<Zahl>) this.stapelToDo.get( 0);
         this.stapelToDo.remove( 0);
      }
   }
   public void run() {
      System.out.println("Starte Panel-Thread");

      while(this.laufend) {
         if (this.stapelToDo.size() > 0) {
            System.out.println("Konfiguration wird gezeichnet!");
         
            this.ladeAktuell();
            repaint();
         
            System.out.println("Verbleibende Konfigurationen: " + this.stapelToDo.size());
         }
        try {
           Thread.sleep( this.intervall);
        } catch (InterruptedException ex) {}
      }
   }
   public void start() {
      System.out.println("Zeichenprozess starten");
      this.laufend = true;
      Thread t = new Thread(this);
      t.start();
   }
   public void stop() {
      this.laufend = false;   
   }
   private synchronized boolean zeichneKonfiguration( Graphics g, Vector<Zahl> zl_aktuell_tmp, int breite, int hoehe){
      if (breite == 0 || hoehe == 0){
         return false;
      }

      int balkenbreite = breite / zl_aktuell_tmp.size();
   
      for ( int i = 0; i< this.zl_aktuell.size(); i++){
         Zahl z_tmp = (Zahl) zl_aktuell_tmp.get( i);
      
         if ( z_tmp.highlight) {
            g.setColor(Color.red);
         } else {
            g.setColor(Color.black);
         }
      
         g.fillRect(i*balkenbreite, hoehe-1-z_tmp.wert, balkenbreite, z_tmp.wert);
      }
      return true;
   }
   public void paintComponent( Graphics g){
      g.setColor(Color.white);
      g.fillRect(0, 0, this.getWidth(), this.getHeight());
   
      if (this.zl_aktuell.size() > 0) {
         if ( !zeichneKonfiguration( g, this.zl_aktuell, this.getWidth(), this.getHeight())){
            System.out.println("Fehler beim Zeichnen");         
         }
      }
   }
  
   public static void main(String[] args) {
     JFrame frame = new JFrame();
     SortSearchPanel panel = new SortSearchPanel();
     frame.add(panel);
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     frame.setSize(800, 600);
     frame.setVisible(true);
    
     Random rand = new Random();
    
     for(int i = 0; i < 1000; i++) {
       int[] zahlen = new int[10];
       boolean[] highlights = new boolean[10];
       for(int j = 0; j < zahlen.length; j++) {
         zahlen[j] = rand.nextInt(500);
         highlights[j] = rand.nextBoolean();
       }
       panel.addZahlen(zahlen, highlights);
     }
    
     panel.start();
   }
}
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Thallius Merkwürdiges Verhalten von Swingworker.cancel() Allgemeine Java-Themen 2
Tommy Nightmare Merkwürdiges Verhalten bei der Datenzuweisung Allgemeine Java-Themen 4
Thallius Swing Merkwürdiges Verhalten beim Panel Tausch Allgemeine Java-Themen 3
Thallius Merkwürdiges StringBuilder verhalten (Char Encoding) Allgemeine Java-Themen 6
V Merkwürdiges For-Loop Problem Allgemeine Java-Themen 7
P Applet-Zugriffsrechte: merkwürdiges Verhalten Allgemeine Java-Themen 4
R Merkwürdiges Verhalten der equals Method Allgemeine Java-Themen 4
M merkwürdiges Verhalten von JUnit4 Allgemeine Java-Themen 2
A Streams: merkwürdiges Verhalten Allgemeine Java-Themen 7
A Streams - merkwürdiges Verhalten Allgemeine Java-Themen 2
R 11 GB File lesen ohne zu extrahieren Filedaten Bereich für Bereich adressieren dann mit Multi-Thread id die DB importieren Allgemeine Java-Themen 3
urmelausdemeis Exception in thread "main" java.lang.Error: Unresolved compilation problem: Allgemeine Java-Themen 7
smarterToby Wie stoppe ich diesen Thread Allgemeine Java-Themen 4
A Thread.sleep Problem Allgemeine Java-Themen 2
J Thread started nur einmal Allgemeine Java-Themen 19
W Server-Thread schreibt nicht alle Dateien Allgemeine Java-Themen 6
OnDemand Logfile pro User / Thread Allgemeine Java-Themen 7
OnDemand Thread / Service abbrechen Allgemeine Java-Themen 3
Thallius Ist meine static Helper Class Thread save? Allgemeine Java-Themen 9
P Swing Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: npoints > xpoints.length || npoints > ypoints.length Allgemeine Java-Themen 5
B Thread.sleep() in EJB Container wie lösen? Allgemeine Java-Themen 11
S Ist das Neuzuweisen von Feldern atomic und damit Thread-Safe? Allgemeine Java-Themen 2
S Exception in thread "main" java.lang.NullPointerException at FamilienApp.main(FamilienApp.java:15) Allgemeine Java-Themen 1
J Einen Thread in einer Schleife Allgemeine Java-Themen 2
E HILFE !! Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/io/FileUtils Allgemeine Java-Themen 4
Flynn Thread-Problem... Allgemeine Java-Themen 2
G Thread-Programmierung Allgemeine Java-Themen 5
S Datei wird nicht gefunden Thread.currentThread().getContextClassLoader().getResourceAsStream() Allgemeine Java-Themen 1
G Beendet sich der Thread selbst?! Allgemeine Java-Themen 3
mrbig2017 Sleep wird ignoriert und der Thread wartet nicht Allgemeine Java-Themen 1
S Thread beenden Allgemeine Java-Themen 9
M Array aus Thread Objekten erstellen Allgemeine Java-Themen 2
Aruetiise Swing JOptionPane ohne denn Thread zu pausieren Allgemeine Java-Themen 1
M Nanosekunden-Pause innerhalb einen Thread-Loops Allgemeine Java-Themen 3
E Thread Exception Allgemeine Java-Themen 6
javaerd Binomialkoeffizient ausrechnen, Exception in thread "main" java.lang.StackOverflowError Allgemeine Java-Themen 6
K Thread Problem Allgemeine Java-Themen 6
W Thread sleep 30 sekunden - wenn keine Antwort bis dahin neu senden Allgemeine Java-Themen 2
H Thread bleibt stehen bei jar in jar Allgemeine Java-Themen 1
J Threads HTTP Request (Thread) dauert lange - in Android Allgemeine Java-Themen 3
F CPU Last eines Thread ausfindig machen Allgemeine Java-Themen 0
V Compiler-Fehler Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 125, Size: 125 Allgemeine Java-Themen 11
Tausendsassa Threads Einen Thread sich selbst schließen lassen Allgemeine Java-Themen 17
P Threads BufferedImage, Thread Concurrency Allgemeine Java-Themen 1
M Klasse in separaten Thread ausführen.Wie genau? Allgemeine Java-Themen 2
llabusch Thread blockiert Dialog Allgemeine Java-Themen 1
J Thread wait() Allgemeine Java-Themen 2
V Thread.sleep und InterruptedException? Allgemeine Java-Themen 1
G Thread nicht von GC zerstört Allgemeine Java-Themen 6
J Wie erschaffe ich einen sicheren Datenaustausch zwischen Thread und Nicht-Threads Allgemeine Java-Themen 8
Sogomn Thread blocken bis Taste gedrückt Allgemeine Java-Themen 5
T Starten vom Thread Allgemeine Java-Themen 3
T Wait/Notify() bei Thread Allgemeine Java-Themen 6
J Exception in thread "main" java.lang.NoClassDefFoundError Allgemeine Java-Themen 4
M Exception in thread "AWT-EventQueue-0" Allgemeine Java-Themen 6
Q Thread wacht nicht auf Allgemeine Java-Themen 7
T Fragen zum Thread-Thema Allgemeine Java-Themen 4
T Threads Input/Output im Thread - Datei ohne Inhalt Allgemeine Java-Themen 1
T Fragen zum Thread-Thema Allgemeine Java-Themen 9
C Threads Variablen in einem Thread Aktualisieren Allgemeine Java-Themen 17
U Thread beenden Allgemeine Java-Themen 3
W Threads Mit Thread und Runtime externe Programme öffnen Allgemeine Java-Themen 0
N Thread interrupt Status debuggen Allgemeine Java-Themen 6
A Thread: Code paralell ausführen in mehreren Instanzen Allgemeine Java-Themen 1
E Threads linkedlist/multi-thread problem Allgemeine Java-Themen 3
B Erkennen, wann Prozess beendet ist, dann Thread beenden. Allgemeine Java-Themen 6
A Thread Fehler absichtlich provozieren Allgemeine Java-Themen 3
B Threads Java Thread kommunizieren Allgemeine Java-Themen 12
N Thread Sicherheit im komplexen Datenmodell Allgemeine Java-Themen 7
K Thread richtig benutzen Allgemeine Java-Themen 3
K Exception in thread "AWT-EventQueue-1" Allgemeine Java-Themen 2
vandread Problem bei kleiner Thread-Übung Allgemeine Java-Themen 2
G Thread erzeugt nicht plausible NullPointerException Allgemeine Java-Themen 7
H Netbeans Warning bei Thread.sleep in Schleife Allgemeine Java-Themen 4
P [Thread] Scheint nicht Sequenziell zu Arbeiten Allgemeine Java-Themen 9
A eine test thread.join() frage Allgemeine Java-Themen 2
tuttle64 Verständnisprobleme mit Thread Locks Allgemeine Java-Themen 4
G Threads Thread bei Datenabfrage Allgemeine Java-Themen 3
S Thread anhalten per Button ? Allgemeine Java-Themen 3
E Thread Programmierung Allgemeine Java-Themen 2
S Threads ServerSocket-Thread soll schlafen, bis er gebraucht wird Allgemeine Java-Themen 2
V Thread schneller stoppen Allgemeine Java-Themen 2
V anstatt thread.join() einfach while schleife? Allgemeine Java-Themen 8
B Mausbewegung im Thread erkennen (hoch/runter) Allgemeine Java-Themen 6
G Linux/C++/Pthreads auf JVM zugreifen, thread safe? Allgemeine Java-Themen 10
K Threads Probleme mit Thread Allgemeine Java-Themen 13
K Threads Thread überprüfen Allgemeine Java-Themen 3
Z Threads Thread für einen Client Allgemeine Java-Themen 9
M Thread JavaFish Allgemeine Java-Themen 10
G Thread.sleep Allgemeine Java-Themen 12
M Threads Viele Aufrufe aus Thread, komisches Verhalten Allgemeine Java-Themen 8
B Threads Main Thread warten auf abgebrochen Task warten lassen Allgemeine Java-Themen 25
K Timer Thread Allgemeine Java-Themen 8
M Methoden Static Methoden und Thread??? Allgemeine Java-Themen 4
N java.lang.IllegalMonitorStateException: object not locked by thread before notify() Allgemeine Java-Themen 2
C Mehothode in anderenm Thread aufrufen Allgemeine Java-Themen 10
R Thread läuft nicht?! Allgemeine Java-Themen 7
R ThreadPool - vorhandene thread liste überprüfen bzw. aufräumen Allgemeine Java-Themen 3
J Anderem Thread Variable mitgeben Allgemeine Java-Themen 2
C Argument an einen Thread übergeben Allgemeine Java-Themen 4

Ähnliche Java Themen

Neue Themen


Oben