Threads Thread und Zugriff auf externe Methode beenden

proteus

Mitglied
Guten Morgen zusammen.

Ich bin gerade dabei ein Programm zu schreiben, dass ein Zahlungssystem für eine Waschanlage sein soll. Es funktioniert soweit auch alles ganz gut.
Es können die diversen Waschprogramme in einer GUI ausgewählt und gestartet werden. Nach dem Auswählen eines Waschprogrammes öffnet sich ein Pop Up Fenster, in dem der ganze Zahlungsvorgang dargestellt wird.
Die Eingaben der Werte kommen von externer Quelle. Diese simuliere ich im Moment noch über die Konsole.
Ich habe bei dem Pop Up Fenster auch einen Abbruch Button implementiert. Es könnte ja sein, dass es sich jemand auf einmal anders überlegt und das Programm doch nicht starten möchte.

Dieser Sieht wie Folgt aus (Code ist nicht vollständig):

Ich starte einen neuen Thread, in dem die while - Schleife solange durchlaufen wird, bis das ganze Geld einbezahlt wurde.

Java:
	Thread moneyInputThread = new Thread() {

		@Override
		public void run() {

				while (temporaryCosts > 0) {

			  temporaryCosts -= washProgramMoneyInput.readInput();
		}
	};
	
moneyInputThread.start();

Die Methode
Code:
readInput()
wartet auf eine Eingabe. Hier treten auch die Probleme auf.

Mein Abbruch Button sieht wiefolgt aus:

Java:
	public void actionPerformed(ActionEvent e) {

		stopWashProgram();	// Rückzahlung des bereits bezahlten Betrages	
		moneyInputThread.interrupt();  // Bricht den Thread ab.
		setInvisible();  // ruft frame.dispose(); auf
	}

Im Prinzip funktioniert das ganz gut. Leider bleibt die Methode
Code:
readInput()
am laufen. Was bedeutet, dass die nächste Eingabe für den bereits abgebrochenen Vorgang zählt.

Gibt es eine Möglichkeit dies zu umgehen? Oder vielleicht der Methode während des Abbruches einen letzten Wert zu senden?

Vielen Dank im Voraus für eure Bemühungen

Gruss
Proteus
 
interrupt() hilft nur genau dann wenn der Thread gerade schläft oder im normalen Ablauf ab und zu selber den zugehörigen Status prüft,

du könntest washProgramMoneyInput, was immer das ist, irgendwie schließen, dann bricht das Lesen bestimmt ab,
oder einen bestimmten Input schicken

evtl. könnte das Lesen mit einem Timeout versehen werden, dann wäre aber weiter darauf zu achten ob nach dem Abbruch-Zeitpunkt noch was neues gelesen wird,
ohne Timeout praktisch genauso, nur dass es evtl. länger dauert, evtl. ewig wenn nichts in washProgramMoneyInput kommt,

ultimativ gibt es noch Thread.stop(), das beendet wohl wirklich den Thread,
ist aber nicht allzu schön/ empfehlenswert
 
Hallo SlaterB,

Danke für deine Antwort.

du könntest washProgramMoneyInput, was immer das ist, irgendwie schließen, dann bricht das Lesen bestimmt ab,
oder einen bestimmten Input schicken

washProgramMoneyInput ist eine Referenz auf ein Objekt der Klasse MoneyInput, welche den ganzen Zahlungs Ablauf regelt.
Ist es möglich das Objekt irgendwie zu "beenden" ? Wenn ich die Referenz auf null setzte, habe ich noch immer den selben Effekt.

Java:
		public void actionPerformed(ActionEvent e) {

			stopWashProgram();		
			washProgramMoneyInput = null;
			moneyInputThread.interrupt();
			setInvisible();
		}

Auch
Code:
Thread.stop()
ändert das ganze nicht. Der Thread wird zwar beendet. Die Methode
Code:
readInput()
läuft jedoch weiter und wartet auf eine Eingabe.


Java:
	public double readInput() {

		System.out.print("Bitte Geld einwerfen: ");
		String inputString = null;
		double receivedMoney = 0.0;
		try {
			inputString = reader.readLine();
		} catch (IOException e) {
			e.printStackTrace();
		}

		try {
			receivedMoney = Double.parseDouble(inputString);
		} catch (NumberFormatException nfe) {

		}

		return receivedMoney;
	}

Kann ich vielleicht in der
Code:
readInput()
Methode etwas machen?
 
in der Tat, das stop() bringt zunächst nichts, wenn aber wieder eine Zeile eingegeben wird kommt der ThreadDeatch-Error,
hätte ich nicht gedacht,
vollständiges Testprogramm dazu unten

ist reader ein BufferedReader oder sonst irgendwas auf System.in?
darauf close() aufzurufen ist sicher nicht allzu anstrebenswert, erstaunlicherweise klappt auch das nicht mal,
dieser Aufruf würde bis zum Ende des Lesens blockiert werden, lauter neues für mich..,

mein nächster Ansatz wäre nun im großen Stil das Einlesen einzuhüllen,
es gibt einen Thread der in Dauerschleife Zeilen von der Konsole einliest und in irgendeine (synchronisierte) Liste schreibt,
andere Programmstellen können daraus lesen oder warten solange leer usw.,
dann wären diese unabhängig von readLine(), würden nicht derart blockiert werden, sondern nur mit sleep() oder wait() warten,
was unterbrochen werden kann,

glaubst du in der Hinrichtung was machen zu können und zu wollen?
vielleicht gibts noch andere einfachere Vorschläge 😉


Java:
public class Test
{
    static BufferedReader reader;

    public static void main(String[] args)
        throws Exception
    {
        reader = new BufferedReader(new InputStreamReader(System.in));

        Thread moneyInputThread = new Thread()
            {

                @Override
                public void run()
                {
                    double temporaryCosts = 1000;
                    while (temporaryCosts > 0)
                    {
                        temporaryCosts -= readInput();
                        System.out.println("tc: "+temporaryCosts);
                    }
                }
            };

        moneyInputThread.start();
        
        Thread.sleep(4000);
        moneyInputThread.stop();
        // reader.close();
        System.out.println("stopped");
    }

    public static double readInput()
    {
        System.out.print("Bitte Geld einwerfen: ");
        String inputString = null;
        double receivedMoney = 0.0;
        try
        {
            inputString = reader.readLine();
            System.out.println("read: "+inputString);
        }
        catch (Throwable e)
        {
            System.out.println("catch: " + e);
            throw new RuntimeException();
        }
        try
        {
            receivedMoney = Double.parseDouble(inputString);
        }
        catch (NumberFormatException nfe)
        {
        }
        return receivedMoney;
    }
}
 
ist reader ein BufferedReader oder sonst irgendwas auf System.in?

Ja, es handelt sich dabei um einen BufferedReader.

glaubst du in der Hinrichtung was machen zu können und zu wollen?
vielleicht gibts noch andere einfachere Vorschläge

Ich werde versuchen mit diesem Ansatz weiter zu arbeiten und eine Lösung dafür finden. Ich lasse es dich wissen, sobald ich weiter gekommen bin.
 

Zurück
Oben