Bereinigen von Threads in Java

9

Ich habe eine Java-Methode, die zwei Berechnungen über einen Eingabesatz durchführt: eine geschätzte und eine genaue Antwort. Die Schätzung kann immer kostengünstig und in verlässlicher Zeit berechnet werden. Die genaue Antwort kann manchmal in akzeptabler Zeit berechnet werden und manchmal nicht (nicht a priori bekannt ... müssen versuchen und sehen).

Was ich einrichten möchte, ist ein Framework, in dem, wenn die genaue Antwort zu lange dauert (eine feste Zeitüberschreitung), stattdessen die vorberechnete Schätzung verwendet wird. Ich dachte, ich würde einen Thread dafür verwenden. Die Hauptkomplikation besteht darin, dass der Code zur Berechnung der genauen Antwort auf einer externen Bibliothek beruht, und daher kann ich die Interrupt-Unterstützung nicht "injizieren".

Ein eigenständiger Testfall für dieses Problem zeigt hier mein Problem:

%Vor%

Dies funktioniert gut Ausgabe ...

%Vor%

Allerdings habe ich einen sehr großen Eingabesatz (in der Größenordnung von Milliarden von Elementen), um meine Analyse durchzuführen, und ich bin unsicher, wie ich die Threads aufräumen soll, die nicht fertig sind (ich will sie nicht im Hintergrund laufen).

Ich weiß, dass verschiedene Methoden, Threads zu zerstören, aus gutem Grund veraltet sind. Ich weiß auch, dass der typische Weg, einen Thread zu stoppen, Interrupts ist. In diesem Fall sehe ich jedoch nicht, dass ich einen Interrupt verwenden kann, da die Methode run() einen einzelnen Aufruf an eine externe Bibliothek weiterleitet.

Wie kann ich in diesem Fall Threads löschen / aufräumen?

    
badroit 14.01.2013, 18:25
quelle

3 Antworten

2

Wenn Sie genug über die externe Bibliothek wissen, wie zum Beispiel:

  1. erwirbt niemals irgendwelche Sperren;
  2. öffnet nie irgendwelche Dateien / Netzwerkverbindungen;
  3. beinhaltet niemals irgendwelche I / O, nicht einmal Logging;

Dann kann sicher sein, Thread#stop darauf zu verwenden. Sie könnten es versuchen und umfangreiche Stresstests durchführen. Irgendwelche Ressourcenlecks sollten sich bald genug manifestieren.

    
Marko Topolnik 14.01.2013, 18:51
quelle
2

Ich würde es versuchen, um zu sehen, ob es auf eine Thread.interrupt () reagiert. Reduzieren Sie Ihre Daten natürlich, damit es nicht für immer läuft, aber wenn es auf einen Interrupt () reagiert, dann sind Sie zu Hause frei. Wenn sie etwas sperren, einen wait () oder sleep () ausführen, muss der Code die InterruptedException verarbeiten und es ist möglich, dass der Autor das getan hat, was richtig war. Sie können es schlucken und fortfahren, aber es ist möglich, dass sie es nicht taten.

Während Sie technisch Thread.stop () aufrufen können, müssen Sie alles über diesen Code wissen, um sicher zu wissen, ob es sicher ist und Sie keine Ressourcen verlieren. Diese Forschung wird Ihnen jedoch zeigen, wie Sie den Code leicht ändern können, um nach interrupt () zu suchen. Sie müssen ziemlich genau den Quellcode haben, um es zu überprüfen, um sicher zu sein, was bedeutet, dass Sie leicht das Richtige tun und die Prüfungen dort hinzufügen könnten, ohne so viel Forschung zu involvieren, um sicher zu sein, Thread.stop () aufzurufen.

Die andere Möglichkeit besteht darin, eine RuntimeException im Thread zu verursachen. Versuchen Sie, eine Referenz, die es haben könnte, auf Null zu setzen oder einige IO (Socket, Dateigriff, usw.) zu schließen. Ändern Sie das Datenfeld, über das es läuft, indem Sie die Größe ändern oder die Daten auf Null setzen. Es gibt etwas, das Sie tun können, damit es eine Ausnahme auslöst, und das wird nicht behandelt und es wird heruntergefahren.

    
chubbsondubs 14.01.2013 18:58
quelle
1

Erweitern Sie die Antwort von chubbsondubs, wenn die Bibliothek des Drittanbieters eine gut definierte API (wie java.util.List oder eine bibliotheksspezifische API) für den Zugriff auf die Eingabedatei verwendet, können Sie die Eingabedatei umbrechen Sie übergeben den Drittanbietercode mit einer Wrapper-Klasse, die Ausnahmen auslöst, z in der List.get -Methode, nachdem ein cancel -Flag gesetzt wurde.

Wenn Sie zum Beispiel ein List an Ihre Drittanbieter-Bibliothek übergeben, ist es möglich, etwas wie folgt zu tun:

%Vor%

Natürlich hängt dieser Ansatz von einigen Dingen ab:

  1. Sie müssen den Code des Drittanbieters gut genug kennen, um zu wissen, welche Methoden aufgerufen werden, die Sie über Eingabeparameter steuern können.
  2. Der Code von Drittanbietern muss während des gesamten Berechnungsprozesses häufig zu diesen Methoden aufrufen (dh er funktioniert nicht, wenn er alle Daten gleichzeitig in eine interne Struktur kopiert und dort berechnet).
  3. Offensichtlich funktioniert das nicht, wenn die Bibliothek Laufzeitausnahmen abfängt und behandelt und die Verarbeitung fortsetzt.
Alex 14.01.2013 19:22
quelle