While-Schleife mit Wartezeit

MaxAPL

Mitglied
Hallo zusammen,

ich stehe gerade vor einem Problem mit einer while-Schleife. Das Java-Skript ist Teil eines Projektes mit der CFD-Software STAR CCM+.

Ziel ist es, zu testen, ob eine Datei im Ordner vorhanden ist, und wenn nicht, zu warten, bis die Datei vorhanden ist und dies bei jeder Iteration des Berechnungsprozesses.

Wenn die Datei bereits vorhanden ist, gibt es einige Anweisungen zu befolgen.

Mit dem obigen Code funktioniert das Makro so lange, bis sich der benötigte Code nicht im Ordner befindet, und dann wartet die Software auf die Datei

1705497909577.png

Wenn ich die benötigte Datei in den Ordner kopiere, sollte der Java-Code fortgesetzt werden und bei jeder Iteration denselben Prozess durchlaufen.

Das Problem ist, die "InterruptedException" zu setzen, um den Prozess innerhalb der For-Schleife fortzusetzen, wenn die benötigte Datei in den Ordner kopiert wird.


Der Code lautet wie folgt:
Java:
package macro;

import java.util.*;
import java.io.*;
import star.common.*;
import star.base.neo.*;
import star.energy.*;
import star.vis.*;


public class Exchange_Table_TimeStep_with_wait extends StarMacro {

  public void execute() {
    execute0();
  }

synchronized private void execute0() {

    Simulation simulation_0 = getActiveSimulation();

    double Time_step = 1.0;
    double Maximum_Physical_Time = 4.0;
    double n = Maximum_Physical_Time/Time_step;

    // Load the data (table)

        for (int i=0; i <= n-1; i++){
            
        // Get the file in the folder

        File f = new File("V:\\FOLDER\\Temperature_Grid1_"+i+".csv");

            while (!f.isFile())
            {
                try {
                wait();
                }
                catch (InterruptedException e){
                    e.printStackTrace();
                }
            }

            simulation_0.println("File available");

            FileTable fileTable_0 =

            (FileTable) simulation_0.getTableManager().createFromFile(resolvePath("Temperature_Grid1_"+i+".csv"));

            simulation_0.getSimulationIterator().run(1,true);

            simulation_0.println("Value of i is "+i);
            
            }
    }
 }

Vielen Dank im Voraus,
Max
 

KonradN

Super-Moderator
Mitarbeiter
Hier bin ich jetzt unsicher, was Du genau erreichen willst. Mit wait() hältst Du den Thread ja erst einmal komplett an und die Frage ist: an welcher Stelle möchtest Du denn den Thread wieder aufwecken? Es müsste dann ja an irgend einer Stelle auf der Instanz, auf der Du wait() aufgerufen hast, ein notify() aufgerufen werden (oder ein notifyAll() auf beliebigem Objekt).

Evtl. willst Du nur eine kurze Pause haben? Also statt wait() ein Thread.sleep(100) oder so - dann wartet der Thread 0,1 Sekunde und läuft dann weiter. Du kannst die Zeit natürlich anpassen.
 

MaxAPL

Mitglied
Hallo @KonradN,

Danke für deine Antwort.

Ja genau, das hatte ich mehrmals in Forums gelesen, das mit den notify(). Bei mir würde nur ein Thread vorhanden sein. Das Problem für mich liegt darin, wie stelle ich dieser Thread ein.

Nein, keine Pause sondern warten bis die Datei im Ordner liegt, sodass die Anweisungen innerhlab der for-loop weiter geführt werden können,

Zunächst habe ich eine for-loop für jeden Zeitschritt meiner Simulation.

Für jeden Zeitschritt sollte zuerst überprüft, ob die benötige Datei im Ordner liegt.

Falls ja --> die folgenden Anweisungen folgen

Java:
simulation_0.println("File available");

            FileTable fileTable_0 =

            (FileTable) simulation_0.getTableManager().createFromFile(resolvePath("Temperature_Grid1_"+i+".csv"));

            simulation_0.getSimulationIterator().run(1,true);

            simulation_0.println("Value of i is "+i);

Falls nein --> warten bis die Datei im Ordner liegt, und dann wenn die vorhanden ist, die Anweisungen wie oben folgen.
 

KonradN

Super-Moderator
Mitarbeiter
keine Pause sondern warten bis die Datei im Ordner liegt, sodass die Anweisungen innerhlab der for-loop weiter geführt werden können,
Ja, das ginge auch anders. Aber das verkompliziert den Code etwas und ich weiss nicht, ob es wirklich zielführend ist.

Es gibt einen WatchService, mit dem Du das Filesystem überwachen kannst:

Über java.nio.FileService kannst Du ein WatchService erzeugen. Der Ablauf sollte so sein:
  • Du erzeugst eine Instanz von java.nio.FileService
  • Du erzeugst eine Instant von java.nio.Path von dem Verzeichnis, das Du überwachen willst
  • Du registrierst den WatchService über Path.register und gibst da mit an, was Du für Events haben willst. ENTRY_CREATE dürfte das dann vermutlich sein.
  • Du holst den WatchKey über WatchService.take()
  • Nun kannst Du Events abfragen (WatchKey.take() und nicht WatchKey.pollEvents()) - dann hast Du bei take() ein Event, das Du auswerten kannst.

Die Links zu der Dokumentation der jeweiligen Methoden habe ich jetzt nicht heraus gesucht. Das sollte aber kein Problem sein für Dich hoffe ich. Ansonsten einfach kurz melden und ich (oder jemand anderes) würde Dir den Weg erläutern.

Und evtl. noch den Hinweis: Wenn Du zeitnah informiert wirst, dann kann es sein:
  • dass die Datei noch gesperrt ist bei exklusivem Zugriff (unter Windows durchaus nicht unüblich)
  • dass die Datei noch nicht fertig geschrieben wurde und Du daher unvollständige Daten bekommst.
 

MaxAPL

Mitglied
Okay, sieht komplexer aus als erwartet.

Ich habe gedacht, dass es ein einfacher Weg geben wurde, um von dieser Wait raus zu gehen und dann die weiter Anweisungen folgen.

Mit einem Thread wäre es nicht zu machen ? Insbesondere, wir können wir diese Thread einstellen mit dieser InterruptException?

Java:
catch (InterruptedException e){
                    e.printStackTrace();
                }

Ich möchte gern alles in den "synchronized private void execute0() " haben, wenne es machbar ist.
 

KonradN

Super-Moderator
Mitarbeiter
Du musst ja irgendwie zu der Information kommen, dass die Datei da ist. Das, was Du dazu machen musst, kannst Du natürlich in eine andere Klasse verlagern, aber es macht natürlich keinen Sinn, mit zwei Thread zu arbeiten, wenn Du einfach den Ablauf hast, dass Thread 1 den zweiten Thread startet und dann wartet und dann läuft der zweite Thread und wenn er fertig ist, weckt er Thread 1 und beendet sich. Dann kann der erste Thread auch gleich durch laufen.

Das würde nur Sinn machen, wenn Du z.B. mehrere Threads hast und Du die dann nur Synchronisieren willst. Dazu dienen die wait / notify Methoden in erster Linie.

Aber natürlich liesse sich sowas abbilden. So eine FileWatcher Klasse, die mehrere Dateien prüfen kann und die einen blockierenden Aufruf hinzu gefügt hat, könnte z.B. so aussehen (Das ist aber ein Schnellschuss. Ich habe da versucht, die Zugriffe, die synchronisiert sein müssen, zu synchronisieren. Aber ich habe da jetzt nicht wirklich viel Zeit hinein gesteckt):
Java:
package de.kneitzel;

import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class FileWatcher {

    private Thread fileWatcherThread;

    private volatile boolean shouldRun = true;

    private List<Path> pathsToWatch = new ArrayList<>();

    public void stop() {
        shouldRun = false;
    }

    public boolean isRunning() {
        return fileWatcherThread != null && fileWatcherThread.isAlive();
    }

    public void waitForPath(Path pathToWatch) {
        synchronized(pathsToWatch) {
            pathsToWatch.add(pathToWatch);
        }
        
        if (!isRunning()) {
            start();
        }
        try {
            synchronized(pathToWatch) {
                pathToWatch.wait();
            }
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        } catch (IllegalMonitorStateException ex) {
            ex.printStackTrace();
        }
    }

    private void start() {
        System.out.println("Starting FileWatcher Thread...");
        shouldRun = true;
        if (isRunning()) return;

        fileWatcherThread = new Thread(this::doWatch);
        fileWatcherThread.start();
    }

    private void doWatch() {
        while (shouldRun) {
            synchronized(pathsToWatch) {
                if (pathsToWatch.isEmpty()) return;

                Iterator<Path> iterator = pathsToWatch.iterator();
                while (iterator.hasNext()) {
                    Path path = iterator.next();

                    if (path.toFile().exists()) {
                        synchronized (path) {
                            path.notify();
                        }
                        iterator.remove();
                    }
                }
            }

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

Ein möglicher Aufruf (damit habe ich einen schnellen Test gemacht):
Java:
        FileWatcher watcher = new FileWatcher();
        System.out.println("Waiting for /Users/konrad/test.txt");
        watcher.waitForPath(Paths.get("/Users/konrad/test.txt"));
        System.out.println("done waiting ...");

Aber noch einmal ganz deutlich: Wenn Du nur auf ein einziges File wartest, dann ist das viel zu komplex! Warte einfach in einer Schleife a.la.
Java:
while (!f.isFile()) {
    try {
        Thread.sleep(50);
    }
    catch (InterruptedException e) {
        e.printStackTrace();
    }
}

Wenn Du das in eine Methode "waitForFile" packst, dann hast Du unter dem Strich das gleiche Verhalten. Mit der gegebenen Klasse hast Du nur einen Vorteil, wenn Du mehrere Threads hast, die so warten, weil dann nur ein Thread aktiv wartet und nicht alle.
 

MaxAPL

Mitglied
Okay danke. Ja ich wollte eigentlich nur ein Prozess haben und sollte nur auf einziges File warten.
In den letzten Code, mit "Thread.sleep(50)" wartet den Prozess 50ms, aber ich weiß nicht wann den File im Ordner liegen würde.
 

KonradN

Super-Moderator
Mitarbeiter
Okay danke. Ja ich wollte eigentlich nur ein Prozess haben und sollte nur auf einziges File warten.
In den letzten Code, mit "Thread.sleep(50)" wartet den Prozess 50ms, aber ich weiß nicht wann den File im Ordner liegen würde.
Dazu hast Du ja eine while Schleife. Dieses Warten wird also so oft gemacht, wie notwendig. Und es gibt kein Timeout.

Das sleep dient nur, dass man eine unnötige Last vermeidet. Du kannst es prinzipiell auch einfach mit
while (!f.isFile()) {}
versuchen (nur testweise!)
Das wird funktionieren, aber Du solltest dann einmal schauen, wie die CPU belastet ist - sobald er wartet wird eine Core auf 100% gehen.

Daher so ein Sleep. Das ist übrigens eine Sache, die man als statische Methode in eine Klasse Threads / ThreadUtils machen kann, denn so ein Sleep braucht man doch hin und wieder mal.
 

MaxAPL

Mitglied
Guten Tag,

Wenn Du nur auf ein einziges File wartest, dann ist das viel zu komplex! Warte einfach in einer Schleife a.la.
Java:
Code:
while (!f.isFile()) {
    try {
        Thread.sleep(50);
    }
    catch (InterruptedException e) {
        e.printStackTrace();
    }
}
Das ist eigentlich den Ziel. Jedoch funktionniert es nicht, da nach den 50 ms, wurde die Simulation gestoppt und wartet nicht bis die Datei im Ordner liegt.

Wie kann ich um das Problem gehen?
 

KonradN

Super-Moderator
Mitarbeiter
Das ist eher kein Problem mit dem Java Code (so dieser so ist wie angezeigt) sondern vermutlich eher ein Problem von der Simulationssoftware (Star ccm+?) Aber ich kenne diese Software nicht und die Dokumentation war jetzt so auf Anhieb auch nicht direkt online zu finden, daher kann ich Dir nicht weiterhelfen.

Was ich Dir sagen kann: Der Thread, der da in dieser Schleife ist, bleibt in der Schleife, bis die Datei da ist. Aber natürlich kann die Software auf anderen Threads weiter laufen und dann diverse Dinge machen incl. auch dem Abbruch der Simulation. Aber da ich die Software nicht kenne ist das schlicht etwas, das sein könnte.
 

KonradN

Super-Moderator
Mitarbeiter
Ich wünsche Dir viel Erfolg. Evtl. kannst Du mir auch die Dokumentation einmal zusenden (konrad (at) neitzel.de). Wenn ich das richtig gesehen habe auf einer Webseite, dann liegt die Dokumentation nach einer Installation mit auf dem System. Dann könnte ich auch einmal drüber schauen, ob ich diesbezüglich etwas sehe.
 

MaxAPL

Mitglied
Update: ich hatte die for-Schleife für n=4 Dateien parametriert und hatte bereits 3 im Ordner. Daher nach den Import der neuen Datei im Ordner hatte die Simulation gestoppt. Ich habe dann n auf 8 gesetzt zum Testen und funktioniert wunderbar.

Noch vielen Dank für Ihre Unterstützung.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Ranger229 Endless loop in while Schleife Java Basics - Anfänger-Themen 3
M Datentypen While-Schleife eine Java Methode erstellen Java Basics - Anfänger-Themen 3
Ostkreuz While Schleife neustarten Java Basics - Anfänger-Themen 20
S Erste Schritte do-while Schleife Münzwurf Java Basics - Anfänger-Themen 1
S while Schleife Taschenrechner Java Basics - Anfänger-Themen 1
P Best Practice While loop schleife Java Basics - Anfänger-Themen 5
A Erste Schritte Aufgabe mit while Schleife Java Basics - Anfänger-Themen 11
R do while Schleife Verständnisfrage Java Basics - Anfänger-Themen 2
Say Fehlenden Code finden in einer while-Schleife? Java Basics - Anfänger-Themen 11
A Return in While Schleife Java Basics - Anfänger-Themen 6
M Erste Schritte While Schleife / Ausgabe von buchstabe & ASCII Wert Java Basics - Anfänger-Themen 4
J do..while Schleife Java Basics - Anfänger-Themen 14
B Zuweisungen und Methodenaufrufe in Bedingung der while Schleife? Java Basics - Anfänger-Themen 2
JavaBeginner22 Würfeln bis 6 while Schleife Java Basics - Anfänger-Themen 13
L while Schleife mit 2 Bedingung endet nicht Java Basics - Anfänger-Themen 3
D Array mit while-schleife Java Basics - Anfänger-Themen 12
B do while Schleife Java Basics - Anfänger-Themen 3
SergioCK Do while Schleife wiederholen Java Basics - Anfänger-Themen 14
Informatikf Methoden While Schleife Java Basics - Anfänger-Themen 3
M While Schleife? Java Basics - Anfänger-Themen 4
Poppigescorn Quersumme Berechnen mit einer While Schleife Java Basics - Anfänger-Themen 13
M Wie kann ich Werte die in einer While Schleife sind weiter genutzt werden? Java Basics - Anfänger-Themen 7
H Kann eine while-Schleife ein Programm blockieren? Java Basics - Anfänger-Themen 8
O Methode in while-Schleife aufrufen geht nur beim ersten Mal Java Basics - Anfänger-Themen 2
A Wie schaffe ich das eine while Schleife addiert danach subtrahirt? Java Basics - Anfänger-Themen 1
J for /while Schleife Java Basics - Anfänger-Themen 5
A While Schleife - buubelsort methode Java Basics - Anfänger-Themen 2
J Wie kann ich hier eine While schleife einbauen? Java Basics - Anfänger-Themen 3
S While-Schleife geht in Endlosschleife über, warum? Java Basics - Anfänger-Themen 6
S Do-While-Schleife Java Basics - Anfänger-Themen 2
S While Schleife Java Basics - Anfänger-Themen 4
S Do-While Schleife Java Basics - Anfänger-Themen 6
L String in Do-While-Schleife Abbruchkriterium Java Basics - Anfänger-Themen 1
CptK Methoden While-Schleife so lange ausführen, wie Methode etwas zurückgibt Java Basics - Anfänger-Themen 2
B Verschachtelung von For-Schleife in While Schleife Java Basics - Anfänger-Themen 14
G while schleife Java Basics - Anfänger-Themen 11
G while schleife mit array Java Basics - Anfänger-Themen 12
L Scanner schließen in While-Schleife? Java Basics - Anfänger-Themen 2
G While schleife Java Basics - Anfänger-Themen 2
mor16Euro Erste Schritte Wie nennt man eine While oder For schleife die nie Ausgeführt wird Java Basics - Anfänger-Themen 5
C Verständnisfrage bezüglich der Do-While Schleife Java Basics - Anfänger-Themen 9
B OOP While Schleife läuft Endlos durch externen aufruf Java Basics - Anfänger-Themen 2
N while Schleife wird nicht beendet, obwohl Sie hätte breaken sollen Java Basics - Anfänger-Themen 4
B mehrere Werte mit scanner und while schleife einlesen, max berechnen bzw addieren Java Basics - Anfänger-Themen 2
D While Schleife bei Bedarf durch Eingabe stoppen Java Basics - Anfänger-Themen 15
A Erste Schritte while-Schleife Java Basics - Anfänger-Themen 38
X While Do schleife funtioniert nicht Java Basics - Anfänger-Themen 5
J 2 "while"-Anweisungen in einer do-Schleife? Java Basics - Anfänger-Themen 4
W while Schleife und Bedingung Java Basics - Anfänger-Themen 11
T While Schleife funktioniert nicht Java Basics - Anfänger-Themen 14
J Input/Output Strings aneinander reihen mit while schleife Java Basics - Anfänger-Themen 25
S Try-Catch in Verwendung einer while Schleife Java Basics - Anfänger-Themen 2
P a cannot be resolved bei einer do while Schleife Java Basics - Anfänger-Themen 1
J While Schleife Java Basics - Anfänger-Themen 19
Z Return in While-Schleife Java Basics - Anfänger-Themen 7
N Methode mit While-Schleife und If-Bedingung und Array-Initialisierung Java Basics - Anfänger-Themen 4
V Erste Schritte Habe Fragen zu der For und While Schleife als auch Inkrement und Dekrement Java Basics - Anfänger-Themen 4
helldunkel While Schleife trotz false Java Basics - Anfänger-Themen 4
E Threads Thread in While-Schleife nur einmal starten Java Basics - Anfänger-Themen 2
R While-Schleife macht nicht was sie soll Java Basics - Anfänger-Themen 24
b1ck while-Schleife Java Basics - Anfänger-Themen 10
b1ck Integer initialisieren bei do-while-Schleife Java Basics - Anfänger-Themen 11
kilopack15 DoWhile-Schleife als While-Schleife darstellen Java Basics - Anfänger-Themen 9
A While-Schleife funktioniert nicht! Java Basics - Anfänger-Themen 33
A Verständnisproblem Ausgabe Do-While-Schleife Java Basics - Anfänger-Themen 3
E Alphabet mit einer while Schleife ausgeben Java Basics - Anfänger-Themen 3
T while schleife starten , beeneden und wieder Starten Java Basics - Anfänger-Themen 8
W Verständnis Probleme bei der while-Schleife und continue Java Basics - Anfänger-Themen 21
B Passwort prüfen bis eindeutig - while Schleife? Java Basics - Anfänger-Themen 11
$ Multiplikations-Rechner mit while Schleife Java Basics - Anfänger-Themen 8
T Variablen Var aus While-Schleife abfragen -.-' Java Basics - Anfänger-Themen 9
snipesss Schlüsselworte While Schleife Java Basics - Anfänger-Themen 3
snipesss While Schleife Java Basics - Anfänger-Themen 6
A Do-While Schleife; int vergleich Java Basics - Anfänger-Themen 2
K For Schleife in While Schleife umwandeln Java Basics - Anfänger-Themen 5
Ste3et_C0st Dynamische While/For Schleife Java Basics - Anfänger-Themen 7
L do-while-Schleife läuft doppelt, try catch fehler Java Basics - Anfänger-Themen 12
A While und For Schleife Java Basics - Anfänger-Themen 2
C Erste Schritte Frage zur do while- und while-Schleife Java Basics - Anfänger-Themen 4
C Do-While Schleife (Fehler bei der Klammerung?) Java Basics - Anfänger-Themen 8
C while-Schleife wird zuoft durchgeführt Java Basics - Anfänger-Themen 2
F Problem do while Schleife und Scanner Java Basics - Anfänger-Themen 2
F Programm bricht While Schleife nicht ab Java Basics - Anfänger-Themen 4
S Verständnis - Frage mehrere SQL Statements in While Schleife Java Basics - Anfänger-Themen 0
C Erste Schritte Warum ist die While Schleife so schnell? Java Basics - Anfänger-Themen 5
A was wird in der while schleife gemacht Java Basics - Anfänger-Themen 3
A Kleines Abbruch-Problem mit Do-While-Schleife Java Basics - Anfänger-Themen 4
Z Logikfehler do-while Schleife Java Basics - Anfänger-Themen 4
E While-Schleife Java Basics - Anfänger-Themen 6
D Textfield im Game ,Problem: while-Schleife Java Basics - Anfänger-Themen 1
A Probleme mit While Schleife Java Basics - Anfänger-Themen 10
M Fibonacci-Folge mit while-Schleife Java Basics - Anfänger-Themen 4
B Summe aller Zahlen von 1 bis zu dieser Zahl (ohne while oder for schleife) Java Basics - Anfänger-Themen 4
LangUndBreit Erste Schritte 100% cpu auslastung (evtl unendliche while schleife?) Java Basics - Anfänger-Themen 1
T Wie vergleiche ich die Jahre aus der while Schleife die in ( public class) fuer cbx geschrieben sind Java Basics - Anfänger-Themen 5
T while Schleife Java Basics - Anfänger-Themen 22
N While Schleife Erklärung Bitte Java Basics - Anfänger-Themen 3
F Problem mit der While schleife und dem Scanner Java Basics - Anfänger-Themen 2
A do while Schleife wird 2 mal durchlaufen Java Basics - Anfänger-Themen 3
Z Compiler-Fehler do while schleife Java Basics - Anfänger-Themen 4

Ähnliche Java Themen

Neue Themen


Oben