2017-12-13 4 views
1

Sagen wir, ich habe folgendes:Zeit begrenzte Funktion

Funktion requestValue: Ich brauche diese Funktion mehrmals aufrufen. Jedes Mal, wenn ich es anrufe, sollte es einen Wert X berechnen und dann eine andere Funktion submitValue(X) mit dem berechneten Wert als Parameter aufrufen. Wenn die Berechnung jedoch nicht innerhalb von 5 Sekunden abgeschlossen wird, sollte sie submitValue(-1) aufrufen.

Beachten Sie, dass dies nur ein Beispiel von dem ist, was ich brauche, um die Frage so einfach wie möglich zu machen, die Funktionen berechnen nichts (Schlaf wird verwendet, um das Überschreiten des Zeitlimits zu simulieren).

Was ich getan habe ist die Thread-Klasse erweitern, und hat eine Funktion, den Faden zu markieren, wie gestoppt:

class myThread extends Thread{ 
    boolean stop = false; 
    @Override 
    public void run(){ 
     Random rand = new Random(); 
     try { 
      Thread.sleep(200*rand.nextInt(10)); 
     } catch (InterruptedException ex) { 
      Logger.getLogger(myClass.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     if (stop == false) 
      submitValue(1); 
    } 
    void Stop(){ 
     stop = true; 
    } 
} 

Hier ist die requestValue Funktion:

void requestValue(){ 
    myThread thread = new myThread(); 

    Timer myTimer = new Timer(1000 , new ActionListener(){ 
      @Override 
      public void actionPerformed(ActionEvent ae) { 
       thread.Stop(); 
       submitValue(-1); 
      } 
     }  
    ); 
    myTimer.setRepeats(false); 
    myTimer.start(); 
    thread.start(); 
} 

Die submitValue Funktion derzeit nur druckt aus dem Parameter (1 oder -1).

Dadurch wird verhindert, dass die Funktion submitValue(1) bei Überschreitung des Zeitlimits aufgerufen wird, jedoch wird immer submitValue(-1) aufgerufen. Wie kann ich den Hörer wissen lassen, dass submitValue(1) angerufen wurde oder nicht, damit ich ihn nicht nochmal anrufe? Und gibt es einen besseren Weg dies zu tun als meine Art zu arbeiten?

Ein weiteres Problem ist, dass alle 1 s vor allen -1 s gedruckt werden, warum passiert das?

Dank

Antwort

2

Mehrere Dinge. Erweitern Sie zunächst nicht den Thread. Implementieren Sie eine Runnable, die Sie anonym ausführen können, und übergeben Sie diese an den Thread-Konstruktor.

Zweitens, erstellen Sie keinen zweiten Timer-Thread. Das ist übermäßig kompliziert und wahrscheinlich die Ursache Ihres Problems. Lassen Sie stattdessen den Hauptthread blockieren.

Verwenden Sie Thread.join (long millis), um die Zeitüberschreitung auszuführen. Wenn der Thread noch aktiv ist, setzen Sie das Flag "Stop". (Beachten Sie, dass es sich um private volatile handeln sollte, mit einer Methode, um es wahr zu machen. Das flüchtige Schlüsselwort stellt sicher, dass der Worker-Thread den Wert bei der Änderung sehen wird.) Und geben dann -1 zurück. Andernfalls geben Sie den berechneten Wert zurück.