2 Stimmen

Threading in Java

Ich versuche, meinen Haupt-Thread von einem neuen Thread zu starten und nach einiger Zeit das Interrupt-Flag zu setzen. Wenn er dies tut, sollte der gespawnte Thread dieses Flag sehen und sich selbst beenden.

Der Hauptfaden sieht in etwa so aus:

final Thread t = new Thread()
{
    @Override
    public void run()
    {
        f();
    }
};
t.start();
try
{
    t.join(time);
    t.interrupt();
    if(t.isAlive())
    {
        t.join(allowance);
        if(t.isAlive())
            throw new Exception();
    }
}
catch(Exception e)
{
    System.err.println("f did not terminate in the alloted time");
}

Und der gespawnte Thread hat einen Haufen der folgenden Dinge in seinem Code verstreut:

if(Thread.interrupted()) return;

Wenn ich im Debug-Modus bin, funktioniert alles perfekt. Die Unterbrechungsflagge wird vom Hauptthread ausgelöst und vom gespawnten Thread abgefangen. Im normalen Ausführungsmodus scheint der gespawnte Thread das Unterbrechungsflag jedoch nicht zu erhalten, egal wie lange ich die Zulage einstelle.

Weiß jemand, was ich falsch mache?

Hinweis: Ich verwende Ubuntu und bin ein absoluter Neuling in Sachen Linux. Kann das Problem mit dem Betriebssystem zusammenhängen? Ich habe den Code nicht auf einem anderen Betriebssystem getestet.

4voto

emirc Punkte 1753

Hier sind meine Vermutungen:

  • Wenn der Hauptthread die t.interrupt(); der t-Thread hat seine Ausführung bereits beendet.
  • Wenn der Hauptthread die t.interrupt(); im t-Thread gibt es keine weiteren Aufrufe zur Überprüfung interrupted() Flagge.
  • Sie erhalten die Ausnahme als Ergebnis der Ausführung des Codes? Erhalten Sie die Ausnahme, die Sie in Ihrem Code nach "Zulage" Zeit werfen oder Sie haben eine andere wie ThreadInterruptedException oder ähnliches? Versuchen Sie, die Meldung der abgefangenen Ausnahme zu schreiben...

0voto

Matthew Murdoch Punkte 29886

Es sieht so aus, als ob der Aufruf Thread.interrupted() in f() nicht erreicht wird.

Das unterschiedliche Verhalten im Debug- und Run-Modus ist wahrscheinlich auf eine Race Condition zurückzuführen.

0voto

Stephen Denne Punkte 35003

Haben Sie verschachtelte Prüfungen von Thread.interrupted()? Diese Methode löscht das Unterbrechungsflag, so dass der zweite Aufruf false zurückgibt. Sie könnten stattdessen isInterrupted() verwenden.

0voto

Peter Lawrey Punkte 511323

Ich schlage vor, dass Sie die Verwendung eines ExecutorService in Erwägung ziehen, der für diese Art von Aufgaben konzipiert ist und Ihnen auch auf andere Weise helfen kann.

ExecutorService service = Executors.newCachedThreadPool();
Future<ResultType> future = service.submit(new Callable<ResultType() {
   public ResultType call() throws Exception {
      // do soemthing
      return (ResultType) ...;
   }
);
// do anything you like until you need to result.
try {
   ResultType result = future.get(5, TimeUnit.SECONDS);
} catch (TimeoutException timedOut) {
  // handle exception
  // cancel the task, interrupting if still running.
  result.cancel(true);
} catch (ExecutionException taskThrewAnException) {
  // handle exception
}
// when you have finished with the service, which is reusable.
service.shutdown();

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X