zeitgesteuertes Multithreading für ProgressMonitor

  • Themenstarter Themenstarter Gast
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
G

Gast

Gast
Hallo,

ich programmiere gerade in Java ein gößeres Programm, das u. a. umfangreiche Tabellen aus anderen Programmen in JTables meines Programms einliest, was ich jeweils mit ProgessMonitors versehen möchte.

Das Problem ist, dass die Algorithmen, die mit einem ProgressMonitor versehen werden sollen,
teilweise Makros anderer Programme sind. D.h. ich kann das Inkrementieren des Progressmonitors nicht an Zählschleifen oder sonstigen Code des Algorithmus koppeln, da mir
der Code dieser Makros ja nicht vorliegt und es sowieso kein Javacode ist.

Daher bleibt mir nur das zeitgesteuerte Ausführen der Threads. Aber jeder meiner Versuche, die Threads vom ProgressMonitor und vom Algorithmus über die Systemzeit zu synchronisieren, mißlang.

Der unten stehende Coe ist ein kleineres Test-Projekt, in dem prinzipiell dieselbe Situation herrscht wie in meinem Programm: das länger dauernde Ausfüllen einer JTable.
Die Klasse CMain mit JTable und main-Methode, die Klasse Algorithm mit dem Algorithmus-Thread sowie die Klasse Progess mit dem Thread des ProgressMonitor.

Wie kann ich diese beiden Threads derart synchronisieren, dass sich regelmäßig - nur
über die Systemzeit - abwechseln ????
Natürlich soll hier keiner meine Hausaufgaben machen.
Aber wie soll ich am besten vorgehen? Ich hab schon so einiges ausprobiert: join-Methode, synchronized mit wait() und notify(), SwingUtilities, Timer und TimerTask...
Aber es kam jedes Mal nur Käse bei raus. Ich bitte um Nachsicht, wenn ich vielleicht irgendwas Naheliegendes übersehen haben sollte. Ich bin zwar keine Java-Anfängerin, sondern programmier schon recht lange damit, aber mit Multithreading hab ichs das erste Mal zu tun.

Hier der Code:
(Aber wie gesagt: Das ist nur ein Beispiel mit prinzipiell derselben Situation wie in meinem Programm. Hier sind zwar Zählschleifen, aber nicht in meinem Programm. Es hilft also nur eine Synchronisation über die Systemzeit.)

Class CMain:
package multithreading;

Code:
import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
import javax.swing.JPanel;
import javax.swing.JFrame;
import java.awt.GridBagLayout;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import javax.swing.JButton;
import java.lang.*;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import javax.swing.table.*;
import javax.swing.ProgressMonitor;

public class CMain extends JFrame {

	private static final long serialVersionUID = 1L;

	private JPanel jContentPane = null;

	private JScrollPane scrollPane = null;

	private JTable table = null;

	private JButton cmdStart = null;
	
	private DefaultTableModel model;
	
	  //  @jve:decl-index=0:
	
	private Vector spalte;
	
	private ProgressMonitor monitor = new ProgressMonitor (this, "Vorgang läuft.", "Bitte Warten..", 0, 1000); 

	/**
	 * This method initializes scrollPane	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */
	private JScrollPane getScrollPane() {
		if (scrollPane == null) {
			scrollPane = new JScrollPane();
			scrollPane.setViewportView(getTable());
		}
		return scrollPane;
	}

	/**
	 * This method initializes table	
	 * 	
	 * @return javax.swing.JTable	
	 */
	private DefaultTableModel getModel() {
		if (model == null) {
			String [] columns = {"col1", "col2", "col3"};
			String [][] data = {{"data1", "data2", "data3"},
					    {"data4", "data5", "data6"},
					    {"data7", "data8", "data9"}};
			model = new DefaultTableModel(data, columns);
			
		}
		return model;
	}
	
	/**
	 * This method initializes table	
	 * 	
	 * @return javax.swing.JTable	
	 */
	private JTable getTable() {
		if (table == null) {
			table = new JTable(getModel());
		}
		return table;
	}

	/**
	 * This method initializes cmdStart	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getCmdStart() {
		if (cmdStart == null) {
			cmdStart = new JButton();
			cmdStart.setText("START");
			cmdStart.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					System.out.println("actionPerformed()"); // TODO Auto-generated Eventstub 										//actionPerformed()
					Algorithm algo = new Algorithm (getTable(), getModel());
					Progress progress = new Progress(monitor);
					
//					algo.start();
//					progress.start();
				}
				});
		}
		return cmdStart;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				CMain thisClass = new CMain();
				thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				thisClass.setVisible(true);
				
			}
		});
	}

	/**
	 * This is the default constructor
	 */
	public CMain() {
		super();
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setSize(300, 200);
		this.setContentPane(getJContentPane());
		this.setTitle("JFrame");
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
			gridBagConstraints1.gridx = 0;
			gridBagConstraints1.insets = new Insets(5, 5, 5, 5);
			gridBagConstraints1.anchor = GridBagConstraints.SOUTH;
			gridBagConstraints1.gridy = 1;
			GridBagConstraints gridBagConstraints = new GridBagConstraints();
			gridBagConstraints.fill = GridBagConstraints.BOTH;
			gridBagConstraints.gridy = 0;
			gridBagConstraints.weightx = 1.0;
			gridBagConstraints.weighty = 1.0;
			gridBagConstraints.insets = new Insets(5, 5, 5, 5);
			gridBagConstraints.gridx = 0;
			jContentPane = new JPanel();
			jContentPane.setLayout(new GridBagLayout());
			jContentPane.add(getScrollPane(), gridBagConstraints);
			jContentPane.add(getCmdStart(), gridBagConstraints1);
		}
		return jContentPane;
	}

	 }


Class Algorithm:
Code:
package multithreading;

import java.util.Vector;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;

public class Algorithm extends Thread {

	private JTable table;
	private Vector neueZeile;
	private DefaultTableModel model;
	
	public Algorithm (JTable tbl, DefaultTableModel mdl){
		
		table = tbl;
		model = mdl;
	}
	
	public void run (){
		algo();
	}
	/**
	 * Die Methode algo, in die Tabelle, die bereits drei Zielen enthält,
	 * werden weiter 5555 eingelsen, das DefaultTablemodel dafür erweitert.
	 * Davor jeweils längeres Hoch -oder Runterzählen.
	 */
	private void algo (){
		for (int n = 0; n < 5555; n++)	
		{		
			neueZeile = new Vector();
			int counter = 0;
			int i;
			for (i = 0; i < 999999; i++)
			{
				counter++;
			}
			neueZeile.add(n);
			neueZeile.add(counter);
			counter = 0;
			for (i = 0; i < 999999; i++)
			{
				counter--;
			}
			neueZeile.add(counter);
			
			model.insertRow(table.getRowCount(), neueZeile);
		}	
		
		System.out.println("******DONE******");

	}

}


Class Progress:
Code:
package multithreading;

import javax.swing.ProgressMonitor;

public class Progress extends Thread {
	
	private ProgressMonitor monitor;

	public Progress (ProgressMonitor pm){
		
		monitor = pm;
	}
	
	public void run(){
		for (int i = 0; i < 1000; i++)
		{
			monitor.setProgress(i);
			
			try {
				Thread.sleep(100);
			} catch (InterruptedException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		

		}
	}
	
	

}
 
Lol, jetzt sogar dreifachpost^^

Du bekommst nicht schneller Hilfe, wenn du öfter postest!

[edit]Nein, sogar Vierfachpost (einer wurde schon gelöscht) Wow![/edit]
 
Sorry wegen des mehrfachen Postings 😳

Mein Browser zeigte "Seite kann nicht angezeigt werden ..bla...".
Daher dachte ich, dass auch das Posten nicht geklappt hätte.
Hoffe, mir wird trotzdem geholfen. :wink:
 
Du übergibst dem Progress den zu überwachenden Algorithm.
Wenn der Algorithm fertig ist, brichst du ab.
Code:
class Progress extends Thread {
    private ProgressMonitor monitor;
    private Algorithm algo;
    public Progress(ProgressMonitor pm, Algorithm algo){
        this.algo = algo;
        monitor = pm;
    }
    public void run(){
        for (int i = 0; i < 1000; i++) {
            monitor.setProgress(i);
            if(!algo.isAlive()){
                monitor.setProgress(monitor.getMaximum());
                break;
            }
...
        }
    }
}
 
@ Andre Uhres
Erstmal ein großes DANKESCHÖN. Es hat geklappt, zumindest für
einige meiner Einlesevorgänge.

Aber ich hab ein wieteres Problem. Bei den Algorithmen, die über Makros
externer Programme laufen ist es so, daß der ProgressMonitor nur ein paar mal
ganz kurz aufflackert oder gar nicht zu sehen ist, weil der nur Algorithmus-Thead
läuft und der wohl den Prozessor für sich beansprucht und der Progreessmonitor- Thread
gar icht mehr zum Zuge kommt.


Ich hatte daher Thread-Prioritäten für den Algo auf MIN_PRIORITY und für den ProgressMonitor
auf MAX_PRIORITY gesetzt, aber es half nichts. Hab auch versucht mit interrupt() und sleep() den Algo anzuhalten -vergeblich. Kann es sein, dass bei Threads, in denen externe Programme ausgeführt werden, die üblichen Methoden des Multithreadings keine gänzliche kontrolle über die Verteilung der Rechenzeit mehr gewährleisten??? Vielleicht weil es dann schon ein anderer Prozess ist und Threads ja nur Teile
eines Prozesses sind? Oder ist dem nicht so?

Wenn nicht, wie kann ich dafür sorgen, dass der ProgressMonitor auch beim Ausführen eines externen Programms weiterhin Rechenzeit zugeteilt bekommt? Die Threads müssen sich ja wechselseitig ausschließen - also Monitoring.
Aber synchronized mit wait() und notify() wär wohl eher was für Multithreading, das über den Code (I/O etc.) synchronisiert wird. Bei Timer und TimerTask hab ich das Problem, dass ich damit einen Thread ganz abarbeiten lassen müsste. Aber für ein sich Abwechseln der Threads muß der Algorithmus-Thread ja immer an der letzten Stelle weitermachen, an der er aufhörte.
Weiß jemand wie sich das realisieren läßt??
 
Huhu,
weiß keiner ne Antwort? Wär schon hilfreich, wenn mir wenigstens jemand diese Fragen beantworten könnte:

[quote="Gast] Kann es sein, dass bei Threads, in denen externe Programme ausgeführt werden, die üblichen Methoden des Multithreadings keine gänzliche kontrolle über die Verteilung der Rechenzeit mehr gewährleisten??? Vielleicht, weil es dann schon ein anderer Prozess ist und Threads ja nur Teile
eines Prozesses sind? Oder ist dem nicht so?
[/quote]

----

Ansonsten hab ich hierbei auch noch das Problem, dass ich nich genau weiß, wie lang die Einlesevorgänge dauern.
Bei Installatiosvorgängen z. B. gibts doch auch einen Ladebalken, der immer nur von links nach rechts hin -und herläuft und sich daher für Ladevorgänge unbestimmter Dauer gut eignet. Ich hab nach einer entsprechenden Swingkomponente für Java gegoogelt und in der Klassendoku gesucht, aber nichts gefunden.
Gibt es so eine Swingkomponente überhaupt?
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben