Gibt es eine Möglichkeit, einen untergeordneten Thread nach einem bestimmten Zeitlimit in Java zu beenden? Edit: Auch dieser bestimmte Thread kann im schlimmsten Fall blockiert werden (Thread wird verwendet, um auf eine Dateiänderung zu warten und blockiert, bis dieses Ereignis eintritt), also bin ich nicht sicher, dass interrupt() erfolgreich sein wird?Killing Thread nach einem bestimmten Zeitlimit in Java
Antwort
Verwenden Sie , um die Runnable
auszuführen, überprüfen Sie die Methoden, in denen Sie das Zeitlimit angeben können. Z.B.
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.invokeAll(Arrays.asList(new Task()), 10, TimeUnit.MINUTES); // Timeout of 10 minutes.
executor.shutdown();
Hier Task
natürlich implementiert Runnable
.
Gute Vorschläge, aber kann der ExecutorService den Thread auch dann abbrechen, wenn er blockiert ist? – Traker
Es wird den Thread unterbrechen, ja. Wenn Sie es anhängen möchten, verwenden Sie 'ExecutorService # awaistTermination()', siehe auch das Beispiel in der Einführung von Javadoc. – BalusC
IMHO, 'InvokeAll' ist Overkill. Benutze 'executor.submit (new Task()). Get (10, TimeUnit.MINUTES);' –
Warum nicht interrupt()
es nach einer bestimmten Zeit? Ihr erstellter Thread muss in der Lage sein, einen InterruptedException
richtig zu behandeln.
Weitere Informationen zum sauberen Herunterfahren von Threads finden Sie in diesem Artikel (http://www.javaspecialists.eu/archive/Issue056.html).
Siehe auch das Executor/Future-Framework, die nützliche Methoden zum Sammeln von Ergebnissen und/oder Beenden von Threads innerhalb bestimmter Zeitgrenzen bieten.
Der Thread muss nur auf "InterruptedException" reagieren, wenn er einen Anruf tätigt, der ihn auslösen kann. Wenn es sich in einer Schleife dreht, sollte es sein eigenes unterbrochenes Flag mit 'Thread.isInterrupted()' (oder nur 'Thread.interrupted()' prüfen, was den aktuellen Thread impliziert). –
Das Töten eines Threads ist in der Regel eine schlechte Idee aus Gründen, die mit der API-Dokumentation für Thread
verknüpft sind.
Wenn Sie auf das Töten eingestellt sind, verwenden Sie einen ganz neuen Prozess.
Sonst ist die übliche Sache, die Threadabfrage System.nanoTime
zu haben, eine Fahne (mögliches volatile
) abzufragen, eine "Giftpille" oder etwas dieser Art in einer Warteschlange.
Das Töten eines Threads ist möglicherweise kritisch, wenn Sie nicht den Code besitzen, den dieser Thread ausführt, und Sie müssen sicherstellen, dass er tot ist. Manchmal müssen beide Codes in derselben virtuellen Adresse ausgeführt werden. –
@Elazar Es ist fast sicher wichtiger, dass der Prozess stabil bleibt. –
Brian hat Recht, es zu unterbrechen ist sicherer, als den Thread "anzuhalten".
Was passiert, wenn der Thread während der Modifizierung auf ein Objekt einrastet und plötzlich gestoppt wird (wodurch die Sperre aufgehoben wird)? Sie bekommen seltsame Ergebnisse.
Nicht direkt; Ich denke, der einfachste Weg besteht darin,() an diesem Thread mit diesem Zeitlimit beizutreten und den Thread zu unterbrechen, wenn es bis zum Ende des Joins noch nicht fertig ist.
, So
Thread t = ...
t.join(timelimit);
if (t.isAlive) t.interrupt();
Hinweis Ich benutzte Interrupt anstatt es tatsächlich zu töten, es ist viel sicherer. Ich würde auch empfehlen, Executoren zu verwenden, anstatt Threads direkt zu manipulieren.
Verwenden Sie nicht destroy()
, da dies keine Bereinigung durchführt.
Der einfachste Weg ist join()
zu bedienen, wie
try {
thread.join();
} catch (InterruptedException e) {//log exception...}
Sie eine ExecutorService
nutzen könnten. Das wäre sehr sinnvoll, wenn mehrere Threads gleichzeitig ausgeführt werden. Wenn Sie neue Threads erstellen müssen, während andere Threads ausgeführt werden, können Sie dies mit einer BlockingQueue
kombinieren.
Eine ThreadPoolExecutor
(eine ExecutorService
-Implementierung) kann ein BlockingQueue
als Argument nehmen, und Sie können einfach neue Threads der Warteschlange hinzufügen. Wenn Sie fertig sind, beenden Sie einfach die ThreadPoolExecutor
.
private BlockingQueue<Runnable> queue;
...
ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 10, new Long(1000),
TimeUnit.MILLISECONDS, this.queue);
Sie können alle der Warteschlange hinzugefügten Threads zählen. Wenn Sie denken, Sie sind fertig (die Warteschlange leer ist, vielleicht?) Einfach vergleichen Sie diese mit
if (issuedThreads == pool.getCompletedTaskCount()) {
pool.shutdown();
}
Wenn die beiden übereinstimmen, sind Sie fertig. Eine weitere Möglichkeit, den Pool zu beenden ist eine zweite in einer Schleife warten:
try {
while (!this.pool.awaitTermination(1000, TimeUnit.MILLISECONDS));
} catch (InterruptedException e) {//log exception...}
Sie können AOP und eine @Timeable
Anmerkung für Ihre Methode von jcabi-aspects verwenden (Ich bin ein Entwickler):
@Timeable(limit = 1, unit = TimeUnit.SECONDS)
String load(String resource) {
// do something time consuming
}
Wenn das Zeitlimit erreicht ist, wird Ihr Thread interrupted()
Flag auf true
gesetzt und es ist Ihre Aufgabe, diese Situation korrekt zu behandeln und die Ausführung zu stoppen. Normalerweise wird es von Thread.sleep(..)
getan.
Einige hilfreiche Änderungen als Teil JEP 266 in CompletableFuture
seit Java eingeführt wurden 9. orTimeout Methode verwenden, denn jetzt ist es möglich, es zu schreiben:
CompletableFuture.runAsync(thread::run)
.orTimeout(30, TimeUnit.SECONDS)
.exceptionally(throwable -> {
log.error("An error occurred", throwable);
return null;
});
In Java 8, leider, sollten Sie verwenden etwas zusätzlichen Code. Hier ist ein Beispiel für eine Delegation Muster Nutzung mit Hilfe von Lombok:
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import java.time.Duration;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import java.util.concurrent.TimeoutException;
import static lombok.AccessLevel.PRIVATE;
import lombok.AllArgsConstructor;
import lombok.experimental.Delegate;
@AllArgsConstructor(access = PRIVATE)
public class TimeoutableCompletableFuture<T> extends CompletableFuture<T> {
public static TimeoutableCompletableFuture<Void> runAsync(
Runnable runnable) {
return new TimeoutableCompletableFuture<>(
CompletableFuture.runAsync(runnable));
}
@Delegate
private final CompletableFuture<T> baseFuture;
public TimeoutableCompletableFuture<T> orTimeout(Duration duration) {
final CompletableFuture<T> otherFuture = new CompletableFuture<>();
Executors.newScheduledThreadPool(
1,
new ThreadFactoryBuilder()
.setDaemon(true)
.setNameFormat("timeoutable-%d")
.build())
.schedule(() -> {
TimeoutException ex = new TimeoutException(
"Timeout after " + duration);
return otherFuture.completeExceptionally(ex);
}, duration.toMillis(), MILLISECONDS);
return new TimeoutableCompletableFuture<>(
baseFuture.applyToEither(otherFuture, a -> a));
}
}
Natürlich über den Code einfach nur als eine statische Factory-Methode neu geschrieben werden:
public static CompletableFuture<Void> runAsyncOrTimeout(
Runnable runnable, long timeout, TimeUnit unit) {
CompletableFuture<Void> other = new CompletableFuture<>();
Executors.newScheduledThreadPool(
1,
new ThreadFactoryBuilder()
.setDaemon(true)
.setNameFormat("timeoutafter-%d")
.build())
.schedule(() -> {
TimeoutException ex = new TimeoutException(
"Timeout after " + timeout);
return other.completeExceptionally(ex);
}, timeout, unit);
return CompletableFuture.runAsync(runnable).applyToEither(other, a -> a);
}
- 1. Killing Thread verursacht SIGSEGV
- 2. Killing "+" Zeichen nach falscher Syntax
- 3. Einem bestimmten Boost-Thread beitreten
- 4. Java ExecutorService einen bestimmten Thread pausieren/fortsetzen
- 5. Java - Anwendung funktioniert nicht richtig nach einem Thread abstürzt
- 6. Run Java-Thread zu bestimmten Zeiten
- 7. Killing eine Haskell-Binärdatei
- 8. Killing Prozess in Shell Script
- 9. Killing HttpWebRequest Objekt mit Thread.Abort
- 10. Capture Console Ausgabe eines bestimmten Thread in Java
- 11. OutOfMemoryError in einem separaten Java-Thread
- 12. Killing Threads mit Pthreads - C
- 13. Java-Locking in einem Thread, Entsperren in einem anderen
- 14. Java - benachrichtigen Sie einen äußeren Thread von einem inneren Thread
- 15. Killing einen blockierten UDP-Socket
- 16. Einfache Kommunikation mit einem Java-Thread
- 17. Wie die API-repeated-Anfrage mit bestimmten Zeitlimit zu blockieren
- 18. killing Reihe von Prozessen
- 19. Java - Suche nach Dateien in einem Verzeichnis
- 20. nach einem bestimmten Feld gruppiert
- 21. Suche nach bestimmten Wörtern in einem Satz
- 22. Einen Thread in Java stoppen?
- 23. Benötigen mit einem Thread helfen TXT-Dateien in bestimmten Ordnern
- 24. Sind statische Variablen in einem bestimmten Thread initialisiert?
- 25. Killing node.js Arbeiter nach der Funktion ist fertig
- 26. Popup in einem Thread
- 27. Timer in Java Thread
- 28. System.exit in Java Thread
- 29. Stoppen Sie den Thread nach einer bestimmten Zeit
- 30. Machen Sie Thread gehen, um endlich nach einer bestimmten Zeit
Was Sie warten verwenden für die Dateiänderung? Object.wait() oder etwas anderes? – mdma
Eigentlich verwende ich jpathwatch, um nach Dateiänderungen zu suchen und speziell nach 'watchService.take()', das blockiert wird, bis eine Datei erstellt/gelöscht wurde. – Traker